@evolu/common 8.10.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 (144) hide show
  1. package/dist/src/Config.d.ts +22 -22
  2. package/dist/src/Config.d.ts.map +1 -1
  3. package/dist/src/Console.d.ts +62 -7
  4. package/dist/src/Console.d.ts.map +1 -1
  5. package/dist/src/Console.js +20 -4
  6. package/dist/src/Crypto.d.ts +76 -4
  7. package/dist/src/Crypto.d.ts.map +1 -1
  8. package/dist/src/Crypto.js +55 -4
  9. package/dist/src/Error.d.ts +45 -0
  10. package/dist/src/Error.d.ts.map +1 -1
  11. package/dist/src/Error.js +69 -0
  12. package/dist/src/Fs.d.ts +92 -18
  13. package/dist/src/Fs.d.ts.map +1 -1
  14. package/dist/src/Fs.js +2 -0
  15. package/dist/src/Identicon.d.ts +2 -2
  16. package/dist/src/Identicon.js +2 -2
  17. package/dist/src/LeakDetector.d.ts +22 -3
  18. package/dist/src/LeakDetector.d.ts.map +1 -1
  19. package/dist/src/LeakDetector.js +12 -2
  20. package/dist/src/LockManager.d.ts +8 -0
  21. package/dist/src/LockManager.d.ts.map +1 -1
  22. package/dist/src/LockManager.js +6 -0
  23. package/dist/src/Object.d.ts.map +1 -1
  24. package/dist/src/Object.js +5 -0
  25. package/dist/src/Platform.d.ts +47 -7
  26. package/dist/src/Platform.d.ts.map +1 -1
  27. package/dist/src/Platform.js +24 -5
  28. package/dist/src/Random.d.ts +25 -2
  29. package/dist/src/Random.d.ts.map +1 -1
  30. package/dist/src/Random.js +14 -2
  31. package/dist/src/Resource.d.ts +156 -1
  32. package/dist/src/Resource.d.ts.map +1 -1
  33. package/dist/src/Resource.js +201 -72
  34. package/dist/src/Schedule.d.ts +11 -10
  35. package/dist/src/Schedule.d.ts.map +1 -1
  36. package/dist/src/Schedule.js +1 -1
  37. package/dist/src/Sqlite.d.ts +132 -16
  38. package/dist/src/Sqlite.d.ts.map +1 -1
  39. package/dist/src/Sqlite.js +63 -9
  40. package/dist/src/Task.d.ts +15 -4
  41. package/dist/src/Task.d.ts.map +1 -1
  42. package/dist/src/Task.js +41 -15
  43. package/dist/src/Test.d.ts +9 -0
  44. package/dist/src/Test.d.ts.map +1 -1
  45. package/dist/src/Test.js +4 -0
  46. package/dist/src/Time.d.ts +106 -9
  47. package/dist/src/Time.d.ts.map +1 -1
  48. package/dist/src/Time.js +55 -4
  49. package/dist/src/Type.d.ts +1455 -1310
  50. package/dist/src/Type.d.ts.map +1 -1
  51. package/dist/src/Type.js +1274 -517
  52. package/dist/src/WebSocket.d.ts +164 -13
  53. package/dist/src/WebSocket.d.ts.map +1 -1
  54. package/dist/src/WebSocket.js +133 -24
  55. package/dist/src/Worker.d.ts +90 -8
  56. package/dist/src/Worker.d.ts.map +1 -1
  57. package/dist/src/Worker.js +28 -2
  58. package/dist/src/index.d.ts +6 -7
  59. package/dist/src/index.d.ts.map +1 -1
  60. package/dist/src/index.js +2 -3
  61. package/dist/src/local-first/Db.d.ts +52 -3
  62. package/dist/src/local-first/Db.d.ts.map +1 -1
  63. package/dist/src/local-first/Db.js +412 -137
  64. package/dist/src/local-first/Evolu.d.ts +336 -211
  65. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  66. package/dist/src/local-first/Evolu.js +102 -15
  67. package/dist/src/local-first/Owner.d.ts +13 -30
  68. package/dist/src/local-first/Owner.d.ts.map +1 -1
  69. package/dist/src/local-first/Owner.js +13 -30
  70. package/dist/src/local-first/Protocol.d.ts +94 -16
  71. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  72. package/dist/src/local-first/Protocol.js +118 -38
  73. package/dist/src/local-first/Query.d.ts +8 -15
  74. package/dist/src/local-first/Query.d.ts.map +1 -1
  75. package/dist/src/local-first/Schema.d.ts +335 -21
  76. package/dist/src/local-first/Schema.d.ts.map +1 -1
  77. package/dist/src/local-first/Schema.js +214 -17
  78. package/dist/src/local-first/Shared.d.ts +537 -22
  79. package/dist/src/local-first/Shared.d.ts.map +1 -1
  80. package/dist/src/local-first/Shared.js +1437 -234
  81. package/dist/src/local-first/Storage.d.ts +192 -14
  82. package/dist/src/local-first/Storage.d.ts.map +1 -1
  83. package/dist/src/local-first/Storage.js +81 -20
  84. package/dist/src/local-first/Timestamp.d.ts +392 -41
  85. package/dist/src/local-first/Timestamp.d.ts.map +1 -1
  86. package/dist/src/local-first/Timestamp.js +403 -81
  87. package/dist/src/local-first/index.d.ts +0 -1
  88. package/dist/src/local-first/index.d.ts.map +1 -1
  89. package/dist/src/local-first/index.js +0 -1
  90. package/package.json +1 -1
  91. package/src/Assert.test.ts +2 -5
  92. package/src/Config.test.ts +2 -6
  93. package/src/Config.ts +133 -133
  94. package/src/Console.ts +62 -7
  95. package/src/Crypto.ts +76 -4
  96. package/src/Eq.test.ts +2 -3
  97. package/src/Error.test.ts +76 -3
  98. package/src/Error.ts +71 -0
  99. package/src/Fs.ts +92 -18
  100. package/src/Identicon.ts +2 -2
  101. package/src/LeakDetector.ts +22 -3
  102. package/src/LockManager.ts +8 -0
  103. package/src/Object.test.ts +27 -12
  104. package/src/Object.ts +5 -0
  105. package/src/Platform.ts +50 -8
  106. package/src/Random.ts +25 -2
  107. package/src/Resource.test.ts +837 -0
  108. package/src/Resource.ts +235 -15
  109. package/src/Schedule.test.ts +50 -12
  110. package/src/Schedule.ts +24 -14
  111. package/src/Sqlite.ts +137 -17
  112. package/src/Task.test.ts +189 -8
  113. package/src/Task.ts +56 -17
  114. package/src/Test.ts +9 -0
  115. package/src/Time.ts +106 -9
  116. package/src/Type.test.ts +946 -1028
  117. package/src/Type.ts +4195 -3136
  118. package/src/Types.test.ts +4 -14
  119. package/src/WebSocket.ts +313 -40
  120. package/src/Worker.ts +90 -8
  121. package/src/index.ts +15 -6
  122. package/src/local-first/Db.ts +644 -339
  123. package/src/local-first/Evolu.test.ts +686 -21
  124. package/src/local-first/Evolu.ts +450 -228
  125. package/src/local-first/Owner.ts +13 -30
  126. package/src/local-first/Protocol.test.ts +617 -10
  127. package/src/local-first/Protocol.ts +196 -72
  128. package/src/local-first/Query.ts +8 -15
  129. package/src/local-first/Schema.test.ts +143 -0
  130. package/src/local-first/Schema.ts +363 -24
  131. package/src/local-first/Shared.test.ts +7731 -559
  132. package/src/local-first/Shared.ts +2036 -267
  133. package/src/local-first/Storage.ts +218 -32
  134. package/src/local-first/Timestamp.test.ts +344 -70
  135. package/src/local-first/Timestamp.ts +434 -118
  136. package/src/local-first/index.ts +0 -1
  137. package/dist/src/local-first/Error.d.ts +0 -12
  138. package/dist/src/local-first/Error.d.ts.map +0 -1
  139. package/dist/src/local-first/Error.js +0 -6
  140. package/dist/src/local-first/LocalAuth.d.ts +0 -150
  141. package/dist/src/local-first/LocalAuth.d.ts.map +0 -1
  142. package/dist/src/local-first/LocalAuth.js +0 -179
  143. package/src/local-first/Error.ts +0 -17
  144. package/src/local-first/LocalAuth.ts +0 -457
@@ -353,9 +353,6 @@ export interface TypeError<Name extends TypeName = TypeName> {
353
353
  readonly type: Name;
354
354
  }
355
355
  declare const transparentTypeErrorSymbol: unique symbol;
356
- interface TransparentTypeError {
357
- readonly [transparentTypeErrorSymbol]?: true;
358
- }
359
356
  /**
360
357
  * A structured error that directly describes a rejected value.
361
358
  *
@@ -373,6 +370,39 @@ export interface TypeValueError<Name extends TypeName = TypeName> extends TypeEr
373
370
  * @group Core
374
371
  */
375
372
  export type TypeErrorFormatter<Error extends TypeError> = (error: Error) => string;
373
+ /**
374
+ * The common structural shape of every {@link Type}, with its specific type
375
+ * parameters erased.
376
+ *
377
+ * @group Core
378
+ */
379
+ export interface TypeNode {
380
+ readonly name: TypeName;
381
+ readonly "~standard": StandardSchemaV1.Props<unknown, unknown>;
382
+ /** A type-only phantom property that does not exist at runtime. */
383
+ readonly Input: unknown;
384
+ /** A type-only phantom property that does not exist at runtime. */
385
+ readonly CanonicalInput: unknown;
386
+ /** A type-only phantom property that does not exist at runtime. */
387
+ readonly Output: unknown;
388
+ /** A type-only phantom property that does not exist at runtime. */
389
+ readonly Error: TypeError;
390
+ readonly [errorsSymbol]: TypeError;
391
+ readonly [customFromSymbol]: unknown;
392
+ readonly [identityEncodingSymbol]: boolean;
393
+ readonly parent: TypeNode | null;
394
+ readonly fromUnknown: (value: unknown, options?: ValidationOptions) => Result<unknown, TypeError>;
395
+ readonly is: (value: unknown) => boolean;
396
+ }
397
+ /**
398
+ * Configures how container {@link Type} operations report errors.
399
+ *
400
+ * @group Core
401
+ */
402
+ export interface ValidationOptions {
403
+ /** Controls whether container {@link Type} operations return one or all errors. */
404
+ readonly errors: "first" | "all";
405
+ }
376
406
  /**
377
407
  * A formatted validation issue located by its path from the root value.
378
408
  *
@@ -418,28 +448,16 @@ export interface TypeIssue {
418
448
  */
419
449
  export declare const typeErrorToIssues: <T extends TypeNode>(type: T, error: InferErrors<NoInfer<T>>) => NonEmptyReadonlyArray<TypeIssue>;
420
450
  /**
421
- * The common structural shape of every {@link Type}, with its specific type
422
- * parameters erased.
451
+ * Marks a {@link TypeError} that wraps one nested error in `outputError` or
452
+ * `error`.
453
+ *
454
+ * {@link localizeTypes} requires formatters for the nested error instead of the
455
+ * wrapper. The marker property exists only in TypeScript.
423
456
  *
424
457
  * @group Core
425
458
  */
426
- export interface TypeNode {
427
- readonly name: TypeName;
428
- readonly "~standard": StandardSchemaV1.Props<unknown, unknown>;
429
- /** A type-only phantom property that does not exist at runtime. */
430
- readonly Input: unknown;
431
- /** A type-only phantom property that does not exist at runtime. */
432
- readonly CanonicalInput: unknown;
433
- /** A type-only phantom property that does not exist at runtime. */
434
- readonly Output: unknown;
435
- /** A type-only phantom property that does not exist at runtime. */
436
- readonly Error: TypeError;
437
- readonly [errorsSymbol]: TypeError;
438
- readonly [customFromSymbol]: unknown;
439
- readonly [identityEncodingSymbol]: boolean;
440
- readonly parent: TypeNode | null;
441
- readonly fromUnknown: (value: unknown, options?: ValidationOptions) => Result<unknown, TypeError>;
442
- readonly is: (value: unknown) => boolean;
459
+ export interface TransparentTypeError {
460
+ readonly [transparentTypeErrorSymbol]?: true;
443
461
  }
444
462
  declare const outputValidationSymbolType: unique symbol;
445
463
  declare const getRuntimeTypeIssuesSymbolType: unique symbol;
@@ -455,7 +473,7 @@ interface RuntimeTypeIssue {
455
473
  readonly issues: NonEmptyReadonlyArray<RuntimeTypeIssue>;
456
474
  }>;
457
475
  }
458
- type RuntimeGetTypeIssues = (error: TypeError, mode: ValidationOptions["errors"]) => NonEmptyReadonlyArray<RuntimeTypeIssue>;
476
+ type RuntimeGetTypeIssues = (error: TypeError, mode: ValidationOptions["errors"], path: ReadonlyArray<PropertyKey>) => NonEmptyReadonlyArray<RuntimeTypeIssue>;
459
477
  /**
460
478
  * Asserts type equality or validates a value with a {@link Type}.
461
479
  *
@@ -775,23 +793,30 @@ type DeepestFromOperation<Operation> = Operation extends {
775
793
  type NonRootErrors<T extends TypeNode> = T extends {
776
794
  readonly parent: infer Parent extends TypeNode;
777
795
  } ? T["Error"] | NonRootErrors<Parent> : never;
778
- interface FromParentOperations<Output, Error extends TypeError, Boundary extends TypeNode> {
796
+ /**
797
+ * The `.parent` suffixes of a {@link Type} `from` operation.
798
+ *
799
+ * Each `.parent` accepts the Output of the next Type toward the root and
800
+ * returns the errors of every boundary it adds.
801
+ *
802
+ * @group Core
803
+ */
804
+ export interface FromParentOperations<Output, Error extends TypeError, Boundary extends TypeNode> {
779
805
  readonly parent: TypeOperationFn<"from", Boundary["Output"], Output, Error> & ([Boundary["parent"]] extends [infer Parent extends TypeNode] ? FromParentOperations<Output, Error | Boundary["Error"], Parent> : unknown);
780
806
  }
781
807
  type ToOperation<Output, Input, Parent extends TypeNode> = ((value: Output) => Input) & ToParentOperations<Output, Parent>;
782
- interface ToParentOperations<Output, Boundary extends TypeNode> {
783
- readonly parent: ((value: Output) => Boundary["Output"]) & ([Boundary["parent"]] extends [infer Parent extends TypeNode] ? ToParentOperations<Output, Parent> : unknown);
784
- }
785
- type TypeOperationFn<Kind extends "from" | "orThrow" | "orNull", Input, Output, Error extends TypeError> = Kind extends "orNull" ? (value: Input) => Output | null : (value: Input, options?: ValidationOptions) => Kind extends "from" ? Result<Output, Error> : Output;
786
808
  /**
787
- * Configures how container {@link Type} operations report errors.
809
+ * The `.parent` suffixes of a {@link Type} `to` operation.
810
+ *
811
+ * Each `.parent` encodes an Output only as far as the Output of the next Type
812
+ * toward the root.
788
813
  *
789
814
  * @group Core
790
815
  */
791
- export interface ValidationOptions {
792
- /** Controls whether container {@link Type} operations return one or all errors. */
793
- readonly errors: "first" | "all";
816
+ export interface ToParentOperations<Output, Boundary extends TypeNode> {
817
+ readonly parent: ((value: Output) => Boundary["Output"]) & ([Boundary["parent"]] extends [infer Parent extends TypeNode] ? ToParentOperations<Output, Parent> : unknown);
794
818
  }
819
+ type TypeOperationFn<Kind extends "from" | "orThrow" | "orNull", Input, Output, Error extends TypeError> = Kind extends "orNull" ? (value: Input) => Output | null : (value: Input, options?: ValidationOptions) => Kind extends "from" ? Result<Output, Error> : Output;
795
820
  type ConcreteTypeNode = AnyType;
796
821
  declare const validationFailureSymbol: unique symbol;
797
822
  interface ValidationFailure<Error> {
@@ -953,6 +978,31 @@ export declare function createType<Name extends TypeName, ParentType extends Con
953
978
  * @group Construction
954
979
  */
955
980
  export declare const createTypeWithError: <Name extends TypeName, T extends ConcreteTypeNode, Error extends TypeError<Name>>(name: Name & ValidateConcreteTypeName<Name>, type: T & ValidateOutput<T> & (IdentityEncodingOf<T> extends true ? unknown : CompileTimeError<"Type", "Source Type must use identity encoding.">), mapError: (error: InferErrors<T>, value: unknown) => Error, formatError: TypeErrorFormatter<NoInfer<Error>>) => Type<Name, T["Output"], T["Output"], Error>;
981
+ /**
982
+ * The {@link Type} returned by {@link transform}.
983
+ *
984
+ * @group Construction
985
+ */
986
+ export interface TransformType<ParentType extends TypeNode, OutputType extends TypeNode, Name extends TypeName, FromError extends TypeError<Name>, ToOutput extends ParentType["Output"] = ParentType["Output"]> extends Type<Name, ParentType["Input"], OutputType["Output"], TransformError<Name, FromError, TypeFromError<OutputType>>, ParentType, TransformError<Name, FromError, TypeFromError<OutputType>> | InferErrors<ParentType>, ChildCustomFrom<ParentType, OutputType["Output"], TransformError<Name, FromError, TypeFromError<OutputType>>>, CanonicalInputForChild<ParentType, ToOutput>, false> {
987
+ readonly [reflectedTypesSymbol]?: OutputType;
988
+ readonly output: OutputType;
989
+ }
990
+ /**
991
+ * An error produced by {@link transform} while decoding or validating its
992
+ * output.
993
+ *
994
+ * @group Construction
995
+ */
996
+ export type TransformError<Name extends TypeName, OwnError extends TypeError<Name>, OutputError extends TypeError> = OwnError | ([OutputError] extends [never] ? never : TransformOutputError<Name, OutputError>);
997
+ /**
998
+ * Wraps an error produced by the output {@link Type} of {@link transform}.
999
+ *
1000
+ * @group Construction
1001
+ */
1002
+ export interface TransformOutputError<Name extends TypeName, OutputError extends TypeError> extends TypeError<Name>, TransparentTypeError {
1003
+ /** The error returned by the output Type. */
1004
+ readonly outputError: OutputError;
1005
+ }
956
1006
  /**
957
1007
  * Transform {@link Type}.
958
1008
  *
@@ -1075,31 +1125,6 @@ export declare function transform<Name extends TypeName, ParentType extends Conc
1075
1125
  readonly from: (value: ParentType["Output"]) => Result<OutputType["Input"], FromError>;
1076
1126
  readonly to: (value: CanonicalInputOf<OutputType>) => ToOutput;
1077
1127
  }, formatError: [FromError] extends [never] ? never : TypeErrorFormatter<NoInfer<FromError>>): TransformType<ParentType, OutputType, Name, FromError, ToOutput>;
1078
- /**
1079
- * The {@link Type} returned by {@link transform}.
1080
- *
1081
- * @group Construction
1082
- */
1083
- export interface TransformType<ParentType extends TypeNode, OutputType extends TypeNode, Name extends TypeName, FromError extends TypeError<Name>, ToOutput extends ParentType["Output"] = ParentType["Output"]> extends Type<Name, ParentType["Input"], OutputType["Output"], TransformError<Name, FromError, TypeFromError<OutputType>>, ParentType, TransformError<Name, FromError, TypeFromError<OutputType>> | InferErrors<ParentType>, ChildCustomFrom<ParentType, OutputType["Output"], TransformError<Name, FromError, TypeFromError<OutputType>>>, CanonicalInputForChild<ParentType, ToOutput>, false> {
1084
- readonly [reflectedTypesSymbol]?: OutputType;
1085
- readonly output: OutputType;
1086
- }
1087
- /**
1088
- * An error produced by {@link transform} while decoding or validating its
1089
- * output.
1090
- *
1091
- * @group Construction
1092
- */
1093
- export type TransformError<Name extends TypeName, OwnError extends TypeError<Name>, OutputError extends TypeError> = OwnError | ([OutputError] extends [never] ? never : TransformOutputError<Name, OutputError>);
1094
- /**
1095
- * Wraps an error produced by the output {@link Type} of {@link transform}.
1096
- *
1097
- * @group Construction
1098
- */
1099
- export interface TransformOutputError<Name extends TypeName, OutputError extends TypeError> extends TypeError<Name>, TransparentTypeError {
1100
- /** The error returned by the output Type. */
1101
- readonly outputError: OutputError;
1102
- }
1103
1128
  type DeepestFromError<Operation> = DeepestFromOperation<Operation> extends (...args: ReadonlyArray<never>) => infer R ? R extends {
1104
1129
  readonly ok: false;
1105
1130
  readonly error: infer Error extends TypeError;
@@ -1114,6 +1139,10 @@ declare const encoderSymbolType: unique symbol;
1114
1139
  declare const fromSymbolType: unique symbol;
1115
1140
  declare const templateLiteralSyntaxSymbolType: unique symbol;
1116
1141
  declare const templateLiteralSyntaxSymbol: typeof templateLiteralSyntaxSymbolType;
1142
+ declare const checkSymbolType: unique symbol;
1143
+ declare const refinementsSymbolType: unique symbol;
1144
+ type RuntimeCheck = (value: unknown, options: ValidationOptions) => TypeError | undefined;
1145
+ type Refinement = (value: unknown) => Result<unknown, TypeError>;
1117
1146
  /**
1118
1147
  * Type-erased {@link Type} used to traverse and invoke heterogeneous Type nodes
1119
1148
  * at runtime.
@@ -1130,6 +1159,8 @@ type RuntimeTypeNode = Omit<TypeNode, typeof customFromSymbol> & {
1130
1159
  readonly [fromSymbolType]: RuntimeOperation<Result<unknown, TypeError>>;
1131
1160
  readonly [encoderSymbolType]: RuntimeEncoder;
1132
1161
  readonly [getRuntimeTypeIssuesSymbolType]: RuntimeGetTypeIssues;
1162
+ readonly [checkSymbolType]: RuntimeCheck | undefined;
1163
+ readonly [refinementsSymbolType]: ReadonlyArray<Refinement> | undefined;
1133
1164
  readonly [templateLiteralSyntaxSymbolType]?: true;
1134
1165
  };
1135
1166
  /**
@@ -1138,6 +1169,14 @@ type RuntimeTypeNode = Omit<TypeNode, typeof customFromSymbol> & {
1138
1169
  * @group Base
1139
1170
  */
1140
1171
  export declare const Unknown: Type<"Unknown", unknown, unknown, never, null, never, never, unknown, true>;
1172
+ /**
1173
+ * Error returned by {@link Never} for every value.
1174
+ *
1175
+ * @group Base
1176
+ */
1177
+ export interface NeverError extends TypeError<"Never"> {
1178
+ readonly value: unknown;
1179
+ }
1141
1180
  /**
1142
1181
  * A {@link Type} rejecting every value.
1143
1182
  *
@@ -1145,11 +1184,12 @@ export declare const Unknown: Type<"Unknown", unknown, unknown, never, null, nev
1145
1184
  */
1146
1185
  export declare const Never: Type<"Never", never, never, NeverError, null, NeverError, never, never, true>;
1147
1186
  /**
1148
- * Error returned by {@link Never} for every value.
1187
+ * Error returned when `typeof` does not match the expected JavaScript type.
1149
1188
  *
1150
1189
  * @group Base
1151
1190
  */
1152
- export interface NeverError extends TypeError<"Never"> {
1191
+ export interface TypeOfError<Name extends keyof TypeOfOutputByName> extends TypeError<"TypeOf"> {
1192
+ readonly expected: Name;
1153
1193
  readonly value: unknown;
1154
1194
  }
1155
1195
  interface TypeOfOutputByName {
@@ -1160,15 +1200,6 @@ interface TypeOfOutputByName {
1160
1200
  readonly Symbol: symbol;
1161
1201
  readonly Function: globalThis.Function;
1162
1202
  }
1163
- /**
1164
- * Error returned when `typeof` does not match the expected JavaScript type.
1165
- *
1166
- * @group Base
1167
- */
1168
- export interface TypeOfError<Name extends keyof TypeOfOutputByName> extends TypeError<"TypeOf"> {
1169
- readonly expected: Name;
1170
- readonly value: unknown;
1171
- }
1172
1203
  /**
1173
1204
  * A JavaScript string {@link Type} without additional constraints.
1174
1205
  *
@@ -1348,15 +1379,6 @@ export declare const Symbol: Type<"Symbol", symbol, symbol, TypeOfError<"Symbol"
1348
1379
  * @group Base
1349
1380
  */
1350
1381
  export declare const Function: Type<"Function", Function, Function, TypeOfError<"Function">, null, TypeOfError<"Function">, never, Function, true>;
1351
- /**
1352
- * A {@link Type} validating Evolu Type declarations.
1353
- *
1354
- * This is useful when a Type itself crosses an unknown boundary or must be
1355
- * asserted with {@link assertType}.
1356
- *
1357
- * @group Core
1358
- */
1359
- export declare const EvoluType: Type<"EvoluType", AnyType, AnyType, EvoluTypeError, null, EvoluTypeError, never, AnyType, true>;
1360
1382
  /**
1361
1383
  * Any concrete {@link Type}, regardless of its particular type parameters.
1362
1384
  *
@@ -1379,6 +1401,15 @@ export interface AnyType extends TypeNode {
1379
1401
  */
1380
1402
  export interface EvoluTypeError extends TypeValueError<"EvoluType"> {
1381
1403
  }
1404
+ /**
1405
+ * A {@link Type} validating Evolu Type declarations.
1406
+ *
1407
+ * This is useful when a Type itself crosses an unknown boundary or must be
1408
+ * asserted with {@link assertType}.
1409
+ *
1410
+ * @group Core
1411
+ */
1412
+ export declare const EvoluType: Type<"EvoluType", AnyType, AnyType, EvoluTypeError, null, EvoluTypeError, never, AnyType, true>;
1382
1413
  /**
1383
1414
  * Nominal evidence that a value has one object tag.
1384
1415
  *
@@ -1407,11 +1438,6 @@ export interface ObjectTagError<Expected extends TypeName = TypeName> extends Ty
1407
1438
  readonly expected: Expected;
1408
1439
  readonly value: unknown;
1409
1440
  }
1410
- interface ObjectTagOutputByName {
1411
- readonly Date: globalThis.Date;
1412
- readonly Uint8Array: globalThis.Uint8Array;
1413
- readonly ArrayBuffer: globalThis.ArrayBuffer;
1414
- }
1415
1441
  /**
1416
1442
  * Realm-neutral {@link Type} trusting an object's reported tag.
1417
1443
  *
@@ -1481,6 +1507,11 @@ export declare function objectTag<Name extends keyof ObjectTagOutputByName>(name
1481
1507
  export declare function objectTag<Name extends TypeName, OutputType extends ConcreteTypeNode & {
1482
1508
  readonly Output: object;
1483
1509
  }>(name: ValidateConcreteTypeName<Name>, outputType: ValidateOutput<OutputType> & ([ChildTypeNameValidationError<"ObjectTag", OutputType>] extends [never] ? unknown : ChildTypeNameValidationError<"ObjectTag", OutputType>)): ObjectTagType<Name, OutputType>;
1510
+ interface ObjectTagOutputByName {
1511
+ readonly Date: globalThis.Date;
1512
+ readonly Uint8Array: globalThis.Uint8Array;
1513
+ readonly ArrayBuffer: globalThis.ArrayBuffer;
1514
+ }
1484
1515
  declare const objectTagSymbol: unique symbol;
1485
1516
  /**
1486
1517
  * A realm-neutral JavaScript Date {@link Type} for trusted values.
@@ -1508,6 +1539,30 @@ export declare const Uint8Array: Type<"Uint8Array", Uint8Array<ArrayBufferLike>,
1508
1539
  * @group Base
1509
1540
  */
1510
1541
  export declare const ArrayBuffer: Type<"ArrayBuffer", ArrayBuffer, ArrayBuffer, ObjectTagError<"ArrayBuffer">, null, ObjectTagError<"ArrayBuffer">, never, ArrayBuffer, true>;
1542
+ /**
1543
+ * The {@link Type} returned by {@link instanceOf}.
1544
+ *
1545
+ * @group Base
1546
+ */
1547
+ export interface InstanceOfType<Constructor extends InstanceConstructor> extends Type<"InstanceOf", InstanceOfOutput<Constructor>, InstanceOfOutput<Constructor>, InstanceOfError, null, InstanceOfError, never, InstanceOfOutput<Constructor>> {
1548
+ readonly constructor: Constructor;
1549
+ }
1550
+ /**
1551
+ * A JavaScript class constructor accepted by {@link instanceOf}.
1552
+ *
1553
+ * @group Base
1554
+ */
1555
+ export type InstanceConstructor<Instance extends object = object> = (abstract new (...args: ReadonlyArray<never>) => Instance) & {
1556
+ readonly name: string;
1557
+ };
1558
+ /**
1559
+ * Error returned when a value is not an instance of the expected constructor.
1560
+ *
1561
+ * @group Base
1562
+ */
1563
+ export interface InstanceOfError extends TypeValueError<"InstanceOf"> {
1564
+ readonly constructorName: string;
1565
+ }
1511
1566
  /**
1512
1567
  * Instance {@link Type} for one constructor.
1513
1568
  *
@@ -1539,33 +1594,9 @@ export declare const ArrayBuffer: Type<"ArrayBuffer", ArrayBuffer, ArrayBuffer,
1539
1594
  * @group Base
1540
1595
  */
1541
1596
  export declare const instanceOf: <Constructor extends InstanceConstructor>(constructor: ValidateInstanceConstructor<Constructor>) => InstanceOfType<Constructor>;
1542
- /**
1543
- * A JavaScript class constructor accepted by {@link instanceOf}.
1544
- *
1545
- * @group Base
1546
- */
1547
- export type InstanceConstructor<Instance extends object = object> = (abstract new (...args: ReadonlyArray<never>) => Instance) & {
1548
- readonly name: string;
1549
- };
1550
- /**
1551
- * The {@link Type} returned by {@link instanceOf}.
1552
- *
1553
- * @group Base
1554
- */
1555
- export interface InstanceOfType<Constructor extends InstanceConstructor> extends Type<"InstanceOf", InstanceOfOutput<Constructor>, InstanceOfOutput<Constructor>, InstanceOfError, null, InstanceOfError, never, InstanceOfOutput<Constructor>> {
1556
- readonly constructor: Constructor;
1557
- }
1558
1597
  type InstanceOfOutput<Constructor extends InstanceConstructor> = Constructor extends {
1559
1598
  readonly prototype: infer Output extends object;
1560
1599
  } ? Output : InstanceType<Constructor>;
1561
- /**
1562
- * Error returned when a value is not an instance of the expected constructor.
1563
- *
1564
- * @group Base
1565
- */
1566
- export interface InstanceOfError extends TypeValueError<"InstanceOf"> {
1567
- readonly constructorName: string;
1568
- }
1569
1600
  type ValidateInstanceConstructor<Constructor extends InstanceConstructor> = IsUnion<Constructor> extends false ? "prototype" extends keyof Constructor ? Constructor : InstanceConstructorCompileTimeError : InstanceConstructorCompileTimeError;
1570
1601
  type InstanceConstructorCompileTimeError = CompileTimeError<"Type", "Constructor must preserve one concrete constructor. Create a Union Type from separate Instance Types instead of passing a union or erased constructor.">;
1571
1602
  /**
@@ -1596,6 +1627,24 @@ type InstanceConstructorCompileTimeError = CompileTimeError<"Type", "Constructor
1596
1627
  * @group Unions
1597
1628
  */
1598
1629
  export type ValidateLiteral<Expected extends Literal> = IsUnion<Expected> extends false ? {} extends Readonly<Record<`${Expected}`, never>> ? LiteralCompileTimeError : Expected : LiteralCompileTimeError;
1630
+ /**
1631
+ * The {@link Type} returned by {@link literal}.
1632
+ *
1633
+ * @group Unions
1634
+ */
1635
+ export interface LiteralType<Expected extends Literal> extends Type<"Literal", WidenLiteral<Expected>, Expected, LiteralError<Expected>, LiteralParent<Expected>, LiteralError<Expected> | LiteralParentErrors<Expected>, never, CanonicalInputSubset<WidenLiteral<Expected>, CanonicalInputForParent<LiteralParent<Expected>, Expected>>, IdentityEncodingForParent<LiteralParent<Expected>>> {
1636
+ readonly [templateLiteralSyntaxSymbol]: true;
1637
+ readonly expected: Expected;
1638
+ }
1639
+ /**
1640
+ * Error returned when a value does not equal the expected literal.
1641
+ *
1642
+ * @group Unions
1643
+ */
1644
+ export interface LiteralError<Expected extends Literal = Literal> extends TypeError<"Literal"> {
1645
+ readonly expected: Expected;
1646
+ readonly value: unknown;
1647
+ }
1599
1648
  /**
1600
1649
  * Literal {@link Type}.
1601
1650
  *
@@ -1638,27 +1687,9 @@ export type ValidateLiteral<Expected extends Literal> = IsUnion<Expected> extend
1638
1687
  * @group Unions
1639
1688
  */
1640
1689
  export declare const literal: <const Expected extends Literal>(expected: ValidateLiteral<Expected>) => LiteralType<Expected>;
1641
- /**
1642
- * The {@link Type} returned by {@link literal}.
1643
- *
1644
- * @group Unions
1645
- */
1646
- export interface LiteralType<Expected extends Literal> extends Type<"Literal", WidenLiteral<Expected>, Expected, LiteralError<Expected>, LiteralParent<Expected>, LiteralError<Expected> | LiteralParentErrors<Expected>, never, CanonicalInputSubset<WidenLiteral<Expected>, CanonicalInputForParent<LiteralParent<Expected>, Expected>>, IdentityEncodingForParent<LiteralParent<Expected>>> {
1647
- readonly [templateLiteralSyntaxSymbol]: true;
1648
- readonly expected: Expected;
1649
- }
1650
1690
  type LiteralParent<Expected extends Literal> = Expected extends string ? typeof String : Expected extends number ? typeof Number : Expected extends bigint ? typeof BigInt : Expected extends boolean ? typeof Boolean : null;
1651
1691
  type LiteralParentErrors<Expected extends Literal> = LiteralParent<Expected> extends infer Parent extends TypeNode ? InferErrors<Parent> : never;
1652
1692
  type LiteralCompileTimeError = CompileTimeError<"Type", "Expected must be one concrete literal value.">;
1653
- /**
1654
- * Error returned when a value does not equal the expected literal.
1655
- *
1656
- * @group Unions
1657
- */
1658
- export interface LiteralError<Expected extends Literal = Literal> extends TypeError<"Literal"> {
1659
- readonly expected: Expected;
1660
- readonly value: unknown;
1661
- }
1662
1693
  /**
1663
1694
  * Literal {@link Type} accepting only `undefined`.
1664
1695
  *
@@ -1672,7 +1703,47 @@ export declare const Undefined: LiteralType<undefined>;
1672
1703
  */
1673
1704
  export declare const Null: LiteralType<null>;
1674
1705
  /**
1675
- * Union {@link Type}.
1706
+ * The {@link Type} returned by {@link union}.
1707
+ *
1708
+ * @group Unions
1709
+ */
1710
+ export interface UnionType<Members extends AtLeastTwoReadonlyArray<TypeNode>> extends Type<"Union", Members[number]["Input"], Members[number]["Output"], UnionTypeError<Members>, UnionInputParent<Members>, UnionTypeError<Members>, never, CanonicalInputOf<Members[number]>, AllTypesUseIdentityEncoding<Members[number]>> {
1711
+ readonly [templateLiteralSyntaxSymbol]: true;
1712
+ readonly [reflectedTypesSymbol]?: Members[number];
1713
+ readonly members: Members;
1714
+ }
1715
+ /**
1716
+ * A root {@link Type} validating the encoded Inputs accepted by {@link union}.
1717
+ *
1718
+ * @group Unions
1719
+ */
1720
+ export type UnionInputType<Input, Error extends TypeError> = Type<"Union", Input, Input, Error, null, Error, never, Input>;
1721
+ /**
1722
+ * Error returned when every member of a {@link union} rejects an input.
1723
+ *
1724
+ * @group Unions
1725
+ */
1726
+ export type UnionError<Error extends TypeError = TypeError, MemberError extends UnionMemberError<Error> = UnionMemberError<Error>> = [Error] extends [never] ? never : UnionErrorValue<Error, MemberError>;
1727
+ /**
1728
+ * The shape of {@link UnionError} when at least one {@link union} member can
1729
+ * fail.
1730
+ *
1731
+ * @group Unions
1732
+ */
1733
+ export interface UnionErrorValue<Error extends TypeError, MemberError extends UnionMemberError<Error> = UnionMemberError<Error>> extends TypeError<"Union"> {
1734
+ readonly errors: NonEmptyReadonlyArray<MemberError>;
1735
+ }
1736
+ /**
1737
+ * An error returned by one {@link union} member and its index.
1738
+ *
1739
+ * @group Unions
1740
+ */
1741
+ export interface UnionMemberError<Error extends TypeError, Index extends number = number> {
1742
+ readonly index: Index;
1743
+ readonly error: Error;
1744
+ }
1745
+ /**
1746
+ * Union {@link Type}.
1676
1747
  *
1677
1748
  * Use `union(A, B)` when a value may match any one of several Types. Literal
1678
1749
  * values can be passed directly as shorthand for their corresponding
@@ -1819,43 +1890,12 @@ type UnionMemberConcreteTypeError = CompileTimeError<"Type", "Union member must
1819
1890
  type NormalizeUnionMembers<Members extends AtLeastTwoReadonlyArray<TypeNode | Literal>> = {
1820
1891
  readonly [Index in keyof Members]: Members[Index] extends TypeNode ? Members[Index] : Members[Index] extends Literal ? LiteralType<Members[Index]> : never;
1821
1892
  } extends infer Normalized extends AtLeastTwoReadonlyArray<TypeNode> ? Normalized : never;
1822
- /**
1823
- * The {@link Type} returned by {@link union}.
1824
- *
1825
- * @group Unions
1826
- */
1827
- export interface UnionType<Members extends AtLeastTwoReadonlyArray<TypeNode>> extends Type<"Union", Members[number]["Input"], Members[number]["Output"], UnionTypeError<Members>, UnionInputParent<Members>, UnionTypeError<Members>, never, CanonicalInputOf<Members[number]>, AllTypesUseIdentityEncoding<Members[number]>> {
1828
- readonly [templateLiteralSyntaxSymbol]: true;
1829
- readonly [reflectedTypesSymbol]?: Members[number];
1830
- readonly members: Members;
1831
- }
1832
- /**
1833
- * A root {@link Type} validating the encoded Inputs accepted by {@link union}.
1834
- *
1835
- * @group Unions
1836
- */
1837
- export type UnionInputType<Input, Error extends TypeError> = Type<"Union", Input, Input, Error, null, Error, never, Input>;
1838
1893
  type UnionInputParent<Members extends AtLeastTwoReadonlyArray<TypeNode>> = UnionMembersAreLiterals<Members> extends true ? LiteralUnionInputParent<Members> : UnionInputType<Members[number]["Input"], UnionInputTypeError<Members>>;
1839
1894
  type LiteralUnionInputParent<Members extends AtLeastTwoReadonlyArray<TypeNode>, Parents = Members[number]["parent"]> = [Parents] extends [infer Parent extends TypeNode] ? IsUnion<Parent> extends true ? UnionInputType<Members[number]["Input"], UnionInputTypeError<Members>> : UnionInputType<Members[number]["Input"], UnionError<InferErrors<Parent>>> : UnionInputType<Members[number]["Input"], UnionInputTypeError<Members>>;
1840
1895
  type UnionInputTypeError<Members extends AtLeastTwoReadonlyArray<TypeNode>, RootMembers extends TypeNode = RootType<Members[number]>> = IsUnion<RootMembers> extends true ? UnionTypeError<RootUnionMembers<Members>> : UnionError<InferErrors<RootMembers>>;
1841
1896
  type RootUnionMembers<Members extends AtLeastTwoReadonlyArray<TypeNode>> = {
1842
1897
  readonly [Index in keyof Members]: RootType<Members[Index]>;
1843
1898
  } extends infer RootMembers extends AtLeastTwoReadonlyArray<TypeNode> ? RootMembers : never;
1844
- /**
1845
- * Error returned when every member of a {@link union} rejects an input.
1846
- *
1847
- * @group Unions
1848
- */
1849
- export type UnionError<Error extends TypeError = TypeError, MemberError extends UnionMemberError<Error> = UnionMemberError<Error>> = [Error] extends [never] ? never : UnionErrorValue<Error, MemberError>;
1850
- /**
1851
- * An error returned by one {@link union} member and its index.
1852
- *
1853
- * @group Unions
1854
- */
1855
- export interface UnionMemberError<Error extends TypeError, Index extends number = number> {
1856
- readonly index: Index;
1857
- readonly error: Error;
1858
- }
1859
1899
  type UnionTypeError<Members extends AtLeastTwoReadonlyArray<TypeNode>> = UnionMembersAreLiterals<Members> extends true ? CorrelatedUnionError<Members> : [Extract<Members[number], InfallibleTypeNode>] extends [never] ? CorrelatedUnionError<Members> : true extends {
1860
1900
  readonly [Index in keyof Members]: [
1861
1901
  InferErrors<Members[Index]>
@@ -1875,8 +1915,24 @@ type UnionMembersAreLiterals<Members extends AtLeastTwoReadonlyArray<TypeNode>>
1875
1915
  type InfallibleTypeNode = TypeNode & {
1876
1916
  readonly [errorsSymbol]: never;
1877
1917
  };
1878
- interface UnionErrorValue<Error extends TypeError, MemberError extends UnionMemberError<Error> = UnionMemberError<Error>> extends TypeError<"Union"> {
1879
- readonly errors: NonEmptyReadonlyArray<MemberError>;
1918
+ /**
1919
+ * The parsing {@link Type} returned by {@link templateLiteralParser}.
1920
+ *
1921
+ * @group Template literals
1922
+ */
1923
+ export interface TemplateLiteralParserType<Parts extends TemplateLiteralParts> extends Type<"TemplateLiteral", string, TemplateLiteralCaptureTuple<Parts>["Output"], never, TemplateLiteralType<Parts>, InferErrors<TemplateLiteralType<Parts>>, never, TemplateLiteralStringOutput<Parts>, false> {
1924
+ readonly [templateLiteralSyntaxSymbol]: true;
1925
+ readonly [reflectedTypesSymbol]?: TemplateLiteralCaptureTuple<Parts>;
1926
+ readonly output: TemplateLiteralCaptureTuple<Parts>;
1927
+ readonly parts: Parts;
1928
+ }
1929
+ /**
1930
+ * Error returned when a string does not match a template literal declaration.
1931
+ *
1932
+ * @group Template literals
1933
+ */
1934
+ export interface TemplateLiteralError extends TypeError<"TemplateLiteral"> {
1935
+ readonly value: string;
1880
1936
  }
1881
1937
  /**
1882
1938
  * Template literal {@link Type} that parses canonical strings into Tuples.
@@ -2071,17 +2127,6 @@ interface UnionErrorValue<Error extends TypeError, MemberError extends UnionMemb
2071
2127
  * @group Template literals
2072
2128
  */
2073
2129
  export declare const templateLiteralParser: <const Parts extends TemplateLiteralParts>(...parts: { readonly [Index in keyof Parts]: ValidateTemplateLiteralPart<Parts[Index]>; } & TemplateLiteralValidation<Parts>) => TemplateLiteralParserType<Parts>;
2074
- /**
2075
- * The parsing {@link Type} returned by {@link templateLiteralParser}.
2076
- *
2077
- * @group Template literals
2078
- */
2079
- export interface TemplateLiteralParserType<Parts extends TemplateLiteralParts> extends Type<"TemplateLiteral", string, TemplateLiteralCaptureTuple<Parts>["Output"], never, TemplateLiteralType<Parts>, InferErrors<TemplateLiteralType<Parts>>, never, TemplateLiteralStringOutput<Parts>, false> {
2080
- readonly [templateLiteralSyntaxSymbol]: true;
2081
- readonly [reflectedTypesSymbol]?: TemplateLiteralCaptureTuple<Parts>;
2082
- readonly output: TemplateLiteralCaptureTuple<Parts>;
2083
- readonly parts: Parts;
2084
- }
2085
2130
  /**
2086
2131
  * The validating string {@link Type} returned by {@link templateLiteral}.
2087
2132
  *
@@ -2131,16 +2176,17 @@ export declare const templateLiteral: <const Parts extends TemplateLiteralParts>
2131
2176
  type TemplateLiteralParseError<Parts extends TemplateLiteralParts> = TransformError<"TemplateLiteral", TemplateLiteralIsFrameless<Parts> extends true ? never : TemplateLiteralError, TemplateLiteralCaptureTupleError<Parts>>;
2132
2177
  type TemplateLiteralCaptureTupleError<Parts extends TemplateLiteralParts> = TupleElementsError<TemplateLiteralCaptureFromStringError<TemplateLiteralCaptureTypes<Parts>[number]>>;
2133
2178
  type TemplateLiteralCaptureFromStringError<T extends TypeNode> = T extends TypeNode ? string extends RootType<T>["Output"] ? TypeFromError<T> : InferErrors<T> : never;
2179
+ declare const templateLiteralStringBrandSymbol: unique symbol;
2134
2180
  /**
2135
- * Error returned when a string does not match a template literal declaration.
2181
+ * Brands the string Output of a {@link templateLiteral} with a transformed
2182
+ * capture Type.
2183
+ *
2184
+ * TypeScript cannot prove from a string literal alone that such a capture is
2185
+ * canonically encoded, so the string must be validated or created with `to`.
2136
2186
  *
2137
2187
  * @group Template literals
2138
2188
  */
2139
- export interface TemplateLiteralError extends TypeError<"TemplateLiteral"> {
2140
- readonly value: string;
2141
- }
2142
- declare const templateLiteralStringBrandSymbol: unique symbol;
2143
- interface TemplateLiteralStringBrand<Parts extends TemplateLiteralParts> {
2189
+ export interface TemplateLiteralStringBrand<Parts extends TemplateLiteralParts> {
2144
2190
  readonly [templateLiteralStringBrandSymbol]: Parts;
2145
2191
  }
2146
2192
  type TemplateLiteralPart = string | TypeNode;
@@ -2166,6 +2212,13 @@ type TemplateLiteralPartsWidth<Parts extends ReadonlyArray<TemplateLiteralPart>,
2166
2212
  type TemplateLiteralPartWidth<Part extends TemplateLiteralPart> = Part extends string ? TemplateLiteralStringWidth<Part> : Part extends TypeNode ? TemplateLiteralTypeWidth<Part> : never;
2167
2213
  type TemplateLiteralIsFrameless<Parts extends ReadonlyArray<TemplateLiteralPart>, HasVariableCapture extends boolean = false> = Parts extends readonly [infer Head, ...infer Tail] ? TemplateLiteralPartWidth<Extract<Head, TemplateLiteralPart>> extends infer Width ? [Width] extends [null] ? HasVariableCapture extends true ? false : TemplateLiteralIsFrameless<Extract<Tail, ReadonlyArray<TemplateLiteralPart>>, true> : [Width] extends [readonly []] ? TemplateLiteralIsFrameless<Extract<Tail, ReadonlyArray<TemplateLiteralPart>>, HasVariableCapture> : false : false : HasVariableCapture;
2168
2214
  type TemplateLiteralStringWidth<Value extends string, Width extends ReadonlyArray<unknown> = readonly []> = string extends Value ? null : Value extends "" ? Width : Value extends `${infer _CodePoint}${infer Tail}` ? TemplateLiteralStringWidth<Tail, readonly [...Width, unknown]> : null;
2215
+ /**
2216
+ * The {@link Type} returned by {@link brand}.
2217
+ *
2218
+ * @group Construction
2219
+ */
2220
+ export interface BrandType<ParentType extends TypeNode, Name extends TypeName, Error extends TypeError> extends Type<Name, ParentType["Input"], ParentType["Output"] & Brand<Name>, Error, ParentType, Error | InferErrors<ParentType>, ChildCustomFrom<ParentType, ParentType["Output"] & Brand<Name>, Error>, CanonicalInputForChild<ParentType, ParentType["Output"] & Brand<Name>>, IdentityEncodingOf<ParentType>> {
2221
+ }
2169
2222
  /**
2170
2223
  * Branded {@link Type}.
2171
2224
  *
@@ -2205,6 +2258,10 @@ type TemplateLiteralStringWidth<Value extends string, Width extends ReadonlyArra
2205
2258
  * type TypeError,
2206
2259
  * } from "@evolu/common";
2207
2260
  *
2261
+ * interface Int64Error extends TypeError<"Int64"> {
2262
+ * readonly value: bigint;
2263
+ * }
2264
+ *
2208
2265
  * const Int64 = brand(
2209
2266
  * "Int64",
2210
2267
  * BigInt,
@@ -2219,10 +2276,6 @@ type TemplateLiteralStringWidth<Value extends string, Width extends ReadonlyArra
2219
2276
  * // Note the Brand.
2220
2277
  * assertType<Int64, bigint & Brand<"Int64">>();
2221
2278
  *
2222
- * interface Int64Error extends TypeError<"Int64"> {
2223
- * readonly value: bigint;
2224
- * }
2225
- *
2226
2279
  * assertOk(Int64.fromUnknown(42n), 42n);
2227
2280
  *
2228
2281
  * const invalid = Int64.fromUnknown(2n ** 63n);
@@ -2243,11 +2296,12 @@ export declare function brand<Name extends TypeName, ParentType extends Concrete
2243
2296
  /** Creates a validated Brand Type with its own error formatter. */
2244
2297
  export declare function brand<Name extends TypeName, ParentType extends ConcreteTypeNode, Error extends TypeError<NoInfer<Name>>>(name: Name, parent: ValidateBrandParent<Name, ParentType>, validate: (value: ParentType["Output"]) => Result<void, Error>, formatError: TypeErrorFormatter<NoInfer<Error>>): BrandType<ParentType, Name, Error>;
2245
2298
  /**
2246
- * The {@link Type} returned by {@link brand}.
2299
+ * Error returned when a string is not a canonical {@link DateIso}.
2247
2300
  *
2248
- * @group Construction
2301
+ * @group String
2249
2302
  */
2250
- export interface BrandType<ParentType extends TypeNode, Name extends TypeName, Error extends TypeError> extends Type<Name, ParentType["Input"], ParentType["Output"] & Brand<Name>, Error, ParentType, Error | InferErrors<ParentType>, ChildCustomFrom<ParentType, ParentType["Output"] & Brand<Name>, Error>, CanonicalInputForChild<ParentType, ParentType["Output"] & Brand<Name>>, IdentityEncodingOf<ParentType>> {
2303
+ export interface DateIsoError extends TypeError<"DateIso"> {
2304
+ readonly value: string;
2251
2305
  }
2252
2306
  /**
2253
2307
  * Canonical ISO date-time {@link String}.
@@ -2289,12 +2343,12 @@ export interface BrandType<ParentType extends TypeNode, Name extends TypeName, E
2289
2343
  export declare const DateIso: BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "DateIso", DateIsoError>;
2290
2344
  export type DateIso = typeof DateIso.Output;
2291
2345
  /**
2292
- * Error returned when a string is not a canonical {@link DateIso}.
2346
+ * Error returned when a {@link Date} cannot be represented as {@link DateIso}.
2293
2347
  *
2294
2348
  * @group String
2295
2349
  */
2296
- export interface DateIsoError extends TypeError<"DateIso"> {
2297
- readonly value: string;
2350
+ export interface DateIsoFromDateError extends TypeError<"DateIsoFromDate"> {
2351
+ readonly value: globalThis.Date;
2298
2352
  }
2299
2353
  /**
2300
2354
  * Safely transforms a {@link Date} into a canonical {@link DateIso}.
@@ -2315,12 +2369,12 @@ export interface DateIsoError extends TypeError<"DateIso"> {
2315
2369
  */
2316
2370
  export declare const DateIsoFromDate: TransformType<Type<"Date", Date, Date, ObjectTagError<"Date">, null, ObjectTagError<"Date">, never, Date, true>, BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "DateIso", DateIsoError>, "DateIsoFromDate", DateIsoFromDateError, Date>;
2317
2371
  /**
2318
- * Error returned when a {@link Date} cannot be represented as {@link DateIso}.
2372
+ * Error returned when a bigint is outside the signed 64-bit {@link Int64} range.
2319
2373
  *
2320
- * @group String
2374
+ * @group Number
2321
2375
  */
2322
- export interface DateIsoFromDateError extends TypeError<"DateIsoFromDate"> {
2323
- readonly value: globalThis.Date;
2376
+ export interface Int64Error extends TypeError<"Int64"> {
2377
+ readonly value: bigint;
2324
2378
  }
2325
2379
  /**
2326
2380
  * Signed 64-bit {@link BigInt}.
@@ -2330,11 +2384,12 @@ export interface DateIsoFromDateError extends TypeError<"DateIsoFromDate"> {
2330
2384
  export declare const Int64: BrandType<Type<"BigInt", bigint, bigint, TypeOfError<"BigInt">, null, TypeOfError<"BigInt">, never, bigint, true>, "Int64", Int64Error>;
2331
2385
  export type Int64 = typeof Int64.Output;
2332
2386
  /**
2333
- * Error returned when a bigint is outside the signed 64-bit {@link Int64} range.
2387
+ * Error returned when a bigint is outside the unsigned 64-bit {@link UInt64}
2388
+ * range.
2334
2389
  *
2335
2390
  * @group Number
2336
2391
  */
2337
- export interface Int64Error extends TypeError<"Int64"> {
2392
+ export interface UInt64Error extends TypeError<"UInt64"> {
2338
2393
  readonly value: bigint;
2339
2394
  }
2340
2395
  /**
@@ -2344,15 +2399,6 @@ export interface Int64Error extends TypeError<"Int64"> {
2344
2399
  */
2345
2400
  export declare const UInt64: BrandType<Type<"BigInt", bigint, bigint, TypeOfError<"BigInt">, null, TypeOfError<"BigInt">, never, bigint, true>, "UInt64", UInt64Error>;
2346
2401
  export type UInt64 = typeof UInt64.Output;
2347
- /**
2348
- * Error returned when a bigint is outside the unsigned 64-bit {@link UInt64}
2349
- * range.
2350
- *
2351
- * @group Number
2352
- */
2353
- export interface UInt64Error extends TypeError<"UInt64"> {
2354
- readonly value: bigint;
2355
- }
2356
2402
  /**
2357
2403
  * Reusable factory for creating a {@link Type} with a {@link Brand}.
2358
2404
  *
@@ -2378,6 +2424,10 @@ export interface UInt64Error extends TypeError<"UInt64"> {
2378
2424
  * type TypeError,
2379
2425
  * } from "@evolu/common";
2380
2426
  *
2427
+ * interface TrimmedError extends TypeError<"Trimmed"> {
2428
+ * readonly value: string;
2429
+ * }
2430
+ *
2381
2431
  * const trimmed: BrandFactory<"Trimmed", string, TrimmedError> = (
2382
2432
  * parent,
2383
2433
  * ) =>
@@ -2396,10 +2446,6 @@ export interface UInt64Error extends TypeError<"UInt64"> {
2396
2446
  *
2397
2447
  * assertType<TrimmedString, string & Brand<"Trimmed">>();
2398
2448
  *
2399
- * interface TrimmedError extends TypeError<"Trimmed"> {
2400
- * readonly value: string;
2401
- * }
2402
- *
2403
2449
  * assertOk(TrimmedString.fromUnknown("Evolu"), "Evolu");
2404
2450
  *
2405
2451
  * const invalid = TrimmedString.fromUnknown(" Evolu");
@@ -2443,6 +2489,13 @@ export type BrandFactory<Name extends TypeName, Value, Error extends TypeError<N
2443
2489
  * type ValidateBrandFactoryNumber,
2444
2490
  * } from "@evolu/common";
2445
2491
  *
2492
+ * interface LessThanError<
2493
+ * Max extends number,
2494
+ * > extends TypeError<`LessThan${Max}`> {
2495
+ * readonly value: number;
2496
+ * readonly max: Max;
2497
+ * }
2498
+ *
2446
2499
  * const lessThan =
2447
2500
  * <Max extends number>(
2448
2501
  * max: ValidateBrandFactoryNumber<Max>,
@@ -2467,13 +2520,6 @@ export type BrandFactory<Name extends TypeName, Value, Error extends TypeError<N
2467
2520
  * assertType<typeof LessThan100.name, "LessThan100">();
2468
2521
  * assertType<LessThan100, number & Brand<"LessThan100">>();
2469
2522
  *
2470
- * interface LessThanError<
2471
- * Max extends number,
2472
- * > extends TypeError<`LessThan${Max}`> {
2473
- * readonly value: number;
2474
- * readonly max: Max;
2475
- * }
2476
- *
2477
2523
  * // @ts-expect-error Arithmetic expressions widen to number.
2478
2524
  * lessThan(100 - 1)(Number);
2479
2525
  * ```
@@ -2500,6 +2546,15 @@ export interface IdentifierBrandByCasing {
2500
2546
  readonly "kebab-case": "KebabCaseIdentifier";
2501
2547
  readonly CONSTANT_CASE: "ConstantCaseIdentifier";
2502
2548
  }
2549
+ /**
2550
+ * Error returned when {@link identifier} rejects a string.
2551
+ *
2552
+ * @group String
2553
+ */
2554
+ export interface IdentifierError<Casing extends IdentifierCasing = IdentifierCasing> extends TypeError<IdentifierBrandByCasing[Casing]> {
2555
+ readonly value: string;
2556
+ readonly casing: Casing;
2557
+ }
2503
2558
  /**
2504
2559
  * Adds identifier validation in a naming convention to an existing string Type.
2505
2560
  *
@@ -2541,15 +2596,6 @@ export interface IdentifierBrandByCasing {
2541
2596
  * @group String
2542
2597
  */
2543
2598
  export declare const identifier: <Casing extends IdentifierCasing>(casing: Casing) => BrandFactory<IdentifierBrandByCasing[Casing], string, IdentifierError<Casing>>;
2544
- /**
2545
- * Error returned when {@link identifier} rejects a string.
2546
- *
2547
- * @group String
2548
- */
2549
- export interface IdentifierError<Casing extends IdentifierCasing = IdentifierCasing> extends TypeError<IdentifierBrandByCasing[Casing]> {
2550
- readonly value: string;
2551
- readonly casing: Casing;
2552
- }
2553
2599
  /**
2554
2600
  * A validated camelCase identifier, such as `http2Port`.
2555
2601
  *
@@ -2797,6 +2843,14 @@ export declare const constantCaseToSnakeCase: (value: ConstantCaseIdentifier) =>
2797
2843
  * @group String
2798
2844
  */
2799
2845
  export declare const constantCaseToKebabCase: (value: ConstantCaseIdentifier) => KebabCaseIdentifier;
2846
+ /**
2847
+ * Error returned when {@link capitalized} rejects a string.
2848
+ *
2849
+ * @group String
2850
+ */
2851
+ export interface CapitalizedError extends TypeError<"Capitalized"> {
2852
+ readonly value: string;
2853
+ }
2800
2854
  /**
2801
2855
  * Adds capitalized text validation to an existing string Type.
2802
2856
  *
@@ -2825,14 +2879,6 @@ export declare const constantCaseToKebabCase: (value: ConstantCaseIdentifier) =>
2825
2879
  export declare const capitalized: <ParentType extends ConcreteTypeNode & {
2826
2880
  readonly Output: string;
2827
2881
  }>(parent: ValidateBrandParent<"Capitalized", ParentType>) => ReturnType<typeof createType<"Capitalized", ParentType, ParentType["Output"] & Capitalize<string>, CapitalizedError>>;
2828
- /**
2829
- * Error returned when {@link capitalized} rejects a string.
2830
- *
2831
- * @group String
2832
- */
2833
- export interface CapitalizedError extends TypeError<"Capitalized"> {
2834
- readonly value: string;
2835
- }
2836
2882
  /**
2837
2883
  * Validates capitalized text as TypeScript's `Capitalize<string>`.
2838
2884
  *
@@ -2882,6 +2928,14 @@ export type CapitalizedString = typeof CapitalizedString.Output;
2882
2928
  * @group String
2883
2929
  */
2884
2930
  export declare const capitalize: <S extends string>(value: S) => Capitalize<S>;
2931
+ /**
2932
+ * Error returned when {@link uncapitalized} rejects a string.
2933
+ *
2934
+ * @group String
2935
+ */
2936
+ export interface UncapitalizedError extends TypeError<"Uncapitalized"> {
2937
+ readonly value: string;
2938
+ }
2885
2939
  /**
2886
2940
  * Adds uncapitalized text validation to an existing string Type.
2887
2941
  *
@@ -2910,14 +2964,6 @@ export declare const capitalize: <S extends string>(value: S) => Capitalize<S>;
2910
2964
  export declare const uncapitalized: <ParentType extends ConcreteTypeNode & {
2911
2965
  readonly Output: string;
2912
2966
  }>(parent: ValidateBrandParent<"Uncapitalized", ParentType>) => ReturnType<typeof createType<"Uncapitalized", ParentType, ParentType["Output"] & Uncapitalize<string>, UncapitalizedError>>;
2913
- /**
2914
- * Error returned when {@link uncapitalized} rejects a string.
2915
- *
2916
- * @group String
2917
- */
2918
- export interface UncapitalizedError extends TypeError<"Uncapitalized"> {
2919
- readonly value: string;
2920
- }
2921
2967
  /**
2922
2968
  * Validates uncapitalized text as TypeScript's `Uncapitalize<string>`.
2923
2969
  *
@@ -2962,6 +3008,14 @@ export type UncapitalizedString = typeof UncapitalizedString.Output;
2962
3008
  * @group String
2963
3009
  */
2964
3010
  export declare const uncapitalize: <S extends string>(value: S) => Uncapitalize<S>;
3011
+ /**
3012
+ * Error returned when {@link uppercased} rejects a string.
3013
+ *
3014
+ * @group String
3015
+ */
3016
+ export interface UppercasedError extends TypeError<"Uppercased"> {
3017
+ readonly value: string;
3018
+ }
2965
3019
  /**
2966
3020
  * Adds uppercased text validation to an existing string Type.
2967
3021
  *
@@ -2990,14 +3044,6 @@ export declare const uncapitalize: <S extends string>(value: S) => Uncapitalize<
2990
3044
  export declare const uppercased: <ParentType extends ConcreteTypeNode & {
2991
3045
  readonly Output: string;
2992
3046
  }>(parent: ValidateBrandParent<"Uppercased", ParentType>) => ReturnType<typeof createType<"Uppercased", ParentType, ParentType["Output"] & Uppercase<string>, UppercasedError>>;
2993
- /**
2994
- * Error returned when {@link uppercased} rejects a string.
2995
- *
2996
- * @group String
2997
- */
2998
- export interface UppercasedError extends TypeError<"Uppercased"> {
2999
- readonly value: string;
3000
- }
3001
3047
  /**
3002
3048
  * Validates uppercased text as TypeScript's `Uppercase<string>`.
3003
3049
  *
@@ -3041,6 +3087,14 @@ export type UppercasedString = typeof UppercasedString.Output;
3041
3087
  * @group String
3042
3088
  */
3043
3089
  export declare const uppercase: <S extends string>(value: S) => Uppercase<S>;
3090
+ /**
3091
+ * Error returned when {@link lowercased} rejects a string.
3092
+ *
3093
+ * @group String
3094
+ */
3095
+ export interface LowercasedError extends TypeError<"Lowercased"> {
3096
+ readonly value: string;
3097
+ }
3044
3098
  /**
3045
3099
  * Adds lowercased text validation to an existing string Type.
3046
3100
  *
@@ -3070,15 +3124,7 @@ export declare const lowercased: <ParentType extends ConcreteTypeNode & {
3070
3124
  readonly Output: string;
3071
3125
  }>(parent: ValidateBrandParent<"Lowercased", ParentType>) => ReturnType<typeof createType<"Lowercased", ParentType, ParentType["Output"] & Lowercase<string>, LowercasedError>>;
3072
3126
  /**
3073
- * Error returned when {@link lowercased} rejects a string.
3074
- *
3075
- * @group String
3076
- */
3077
- export interface LowercasedError extends TypeError<"Lowercased"> {
3078
- readonly value: string;
3079
- }
3080
- /**
3081
- * Validates lowercased text as TypeScript's `Lowercase<string>`.
3127
+ * Validates lowercased text as TypeScript's `Lowercase<string>`.
3082
3128
  *
3083
3129
  * Checks the whole string using JavaScript's Unicode lowercase mapping. Empty
3084
3130
  * strings and uncased characters, such as digits and emoji, are valid. Use
@@ -3120,6 +3166,14 @@ export type LowercasedString = typeof LowercasedString.Output;
3120
3166
  * @group String
3121
3167
  */
3122
3168
  export declare const lowercase: <S extends string>(value: S) => Lowercase<S>;
3169
+ /**
3170
+ * Error returned when {@link trimmed} rejects a string.
3171
+ *
3172
+ * @group String
3173
+ */
3174
+ export interface TrimmedError extends TypeError<"Trimmed"> {
3175
+ readonly value: string;
3176
+ }
3123
3177
  /**
3124
3178
  * String {@link Brand} without surrounding whitespace.
3125
3179
  *
@@ -3136,14 +3190,6 @@ export declare const lowercase: <S extends string>(value: S) => Lowercase<S>;
3136
3190
  * @group String
3137
3191
  */
3138
3192
  export declare const trimmed: BrandFactory<"Trimmed", string, TrimmedError>;
3139
- /**
3140
- * Error returned when {@link trimmed} rejects a string.
3141
- *
3142
- * @group String
3143
- */
3144
- export interface TrimmedError extends TypeError<"Trimmed"> {
3145
- readonly value: string;
3146
- }
3147
3193
  /**
3148
3194
  * A {@link String} without surrounding whitespace.
3149
3195
  *
@@ -3171,6 +3217,15 @@ export type TrimmedString = typeof TrimmedString.Output;
3171
3217
  * @group String
3172
3218
  */
3173
3219
  export declare const trim: (value: string) => TrimmedString;
3220
+ /**
3221
+ * Error returned when {@link startsWith} rejects a string.
3222
+ *
3223
+ * @group String
3224
+ */
3225
+ export interface StartsWithError<Prefix extends string = string> extends TypeError<`StartsWith${Prefix}`> {
3226
+ readonly value: string;
3227
+ readonly prefix: Prefix;
3228
+ }
3174
3229
  /**
3175
3230
  * String {@link Brand} requiring an exact, case-sensitive prefix.
3176
3231
  *
@@ -3211,13 +3266,11 @@ export declare const trim: (value: string) => TrimmedString;
3211
3266
  */
3212
3267
  export declare const startsWith: <Prefix extends string>(prefix: Prefix & ValidateLiteral<Prefix>) => BrandFactory<`StartsWith${Prefix}`, string, StartsWithError<Prefix>>;
3213
3268
  /**
3214
- * Error returned when {@link startsWith} rejects a string.
3269
+ * The {@link Type} returned by {@link prefixed}.
3215
3270
  *
3216
3271
  * @group String
3217
3272
  */
3218
- export interface StartsWithError<Prefix extends string = string> extends TypeError<`StartsWith${Prefix}`> {
3219
- readonly value: string;
3220
- readonly prefix: Prefix;
3273
+ export interface PrefixedType<Prefix extends string, T extends TypeNode> extends TransformType<BrandType<typeof String, `StartsWith${Prefix}`, StartsWithError<Prefix>>, T, `Prefixed${Prefix}`, never> {
3221
3274
  }
3222
3275
  /**
3223
3276
  * Decodes a prefixed string with another {@link Type} and restores the prefix
@@ -3273,14 +3326,16 @@ export declare const prefixed: <Prefix extends string>(prefix: Prefix & Validate
3273
3326
  readonly Input: string;
3274
3327
  readonly CanonicalInput: string;
3275
3328
  }>(type: T & ValidateOutput<T> & (string extends T["Input"] ? unknown : PrefixedInputTypeError)) => PrefixedType<Prefix, T>;
3329
+ type PrefixedInputTypeError = CompileTimeError<"Type", "Prefixed Type Input must accept every string.">;
3276
3330
  /**
3277
- * The {@link Type} returned by {@link prefixed}.
3331
+ * Error returned when {@link minLength} rejects a value.
3278
3332
  *
3279
- * @group String
3333
+ * @group Collection
3280
3334
  */
3281
- export interface PrefixedType<Prefix extends string, T extends TypeNode> extends TransformType<BrandType<typeof String, `StartsWith${Prefix}`, StartsWithError<Prefix>>, T, `Prefixed${Prefix}`, never> {
3335
+ export interface MinLengthError<Min extends number = number> extends TypeError<`MinLength${Min}`> {
3336
+ readonly value: ValueWithLength;
3337
+ readonly min: Min;
3282
3338
  }
3283
- type PrefixedInputTypeError = CompileTimeError<"Type", "Prefixed Type Input must accept every string.">;
3284
3339
  /**
3285
3340
  * Minimum-length {@link Brand} for values whose `length` is at least `min`.
3286
3341
  *
@@ -3300,15 +3355,6 @@ type PrefixedInputTypeError = CompileTimeError<"Type", "Prefixed Type Input must
3300
3355
  * @group Collection
3301
3356
  */
3302
3357
  export declare const minLength: <Min extends number>(min: ValidateBrandFactoryNumber<Min>) => BrandFactory<`MinLength${Min}`, ValueWithLength, MinLengthError<Min>>;
3303
- /**
3304
- * Error returned when {@link minLength} rejects a value.
3305
- *
3306
- * @group Collection
3307
- */
3308
- export interface MinLengthError<Min extends number = number> extends TypeError<`MinLength${Min}`> {
3309
- readonly value: ValueWithLength;
3310
- readonly min: Min;
3311
- }
3312
3358
  /**
3313
3359
  * A non-empty {@link TrimmedString}.
3314
3360
  *
@@ -3325,6 +3371,15 @@ export interface MinLengthError<Min extends number = number> extends TypeError<`
3325
3371
  */
3326
3372
  export declare const NonEmptyTrimmedString: BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Trimmed", TrimmedError>, "MinLength1", MinLengthError<1>>;
3327
3373
  export type NonEmptyTrimmedString = typeof NonEmptyTrimmedString.Output;
3374
+ /**
3375
+ * Error returned when {@link maxLength} rejects a value.
3376
+ *
3377
+ * @group Collection
3378
+ */
3379
+ export interface MaxLengthError<Max extends number = number> extends TypeError<`MaxLength${Max}`> {
3380
+ readonly value: ValueWithLength;
3381
+ readonly max: Max;
3382
+ }
3328
3383
  /**
3329
3384
  * Maximum-length {@link Brand} for values whose `length` is at most `max`.
3330
3385
  *
@@ -3344,15 +3399,6 @@ export type NonEmptyTrimmedString = typeof NonEmptyTrimmedString.Output;
3344
3399
  * @group Collection
3345
3400
  */
3346
3401
  export declare const maxLength: <Max extends number>(max: ValidateBrandFactoryNumber<Max>) => BrandFactory<`MaxLength${Max}`, ValueWithLength, MaxLengthError<Max>>;
3347
- /**
3348
- * Error returned when {@link maxLength} rejects a value.
3349
- *
3350
- * @group Collection
3351
- */
3352
- export interface MaxLengthError<Max extends number = number> extends TypeError<`MaxLength${Max}`> {
3353
- readonly value: ValueWithLength;
3354
- readonly max: Max;
3355
- }
3356
3402
  /**
3357
3403
  * A {@link NonEmptyTrimmedString} with at most 100 UTF-16 code units.
3358
3404
  *
@@ -3367,6 +3413,15 @@ export type NonEmptyTrimmedString100 = typeof NonEmptyTrimmedString100.Output;
3367
3413
  */
3368
3414
  export declare const NonEmptyTrimmedString1000: BrandType<BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Trimmed", TrimmedError>, "MinLength1", MinLengthError<1>>, "MaxLength1000", MaxLengthError<1000>>;
3369
3415
  export type NonEmptyTrimmedString1000 = typeof NonEmptyTrimmedString1000.Output;
3416
+ /**
3417
+ * Error returned when {@link length} rejects a value.
3418
+ *
3419
+ * @group Collection
3420
+ */
3421
+ export interface LengthError<Exact extends number = number> extends TypeError<`Length${Exact}`> {
3422
+ readonly value: ValueWithLength;
3423
+ readonly exact: Exact;
3424
+ }
3370
3425
  /**
3371
3426
  * Exact-length {@link Brand} for values whose `length` equals `exact`.
3372
3427
  *
@@ -3387,13 +3442,15 @@ export type NonEmptyTrimmedString1000 = typeof NonEmptyTrimmedString1000.Output;
3387
3442
  */
3388
3443
  export declare const length: <Exact extends number>(exact: ValidateBrandFactoryNumber<Exact>) => BrandFactory<`Length${Exact}`, ValueWithLength, LengthError<Exact>>;
3389
3444
  /**
3390
- * Error returned when {@link length} rejects a value.
3445
+ * Error returned when a string does not match the regular expression supplied
3446
+ * to {@link regex}.
3391
3447
  *
3392
- * @group Collection
3448
+ * @group String
3393
3449
  */
3394
- export interface LengthError<Exact extends number = number> extends TypeError<`Length${Exact}`> {
3395
- readonly value: ValueWithLength;
3396
- readonly exact: Exact;
3450
+ export interface RegexError<Name extends TypeName = TypeName> extends TypeError<Name> {
3451
+ readonly value: string;
3452
+ readonly source: string;
3453
+ readonly flags: string;
3397
3454
  }
3398
3455
  /**
3399
3456
  * String {@link Brand} constrained by a regular expression.
@@ -3438,17 +3495,6 @@ export interface LengthError<Exact extends number = number> extends TypeError<`L
3438
3495
  * @group String
3439
3496
  */
3440
3497
  export declare const regex: <const Name extends TypeName>(name: ValidateConcreteTypeName<Name>, pattern: RegExp) => BrandFactory<Name, string, RegexError<Name>>;
3441
- /**
3442
- * Error returned when a string does not match the regular expression supplied
3443
- * to {@link regex}.
3444
- *
3445
- * @group String
3446
- */
3447
- export interface RegexError<Name extends TypeName = TypeName> extends TypeError<Name> {
3448
- readonly value: string;
3449
- readonly source: string;
3450
- readonly flags: string;
3451
- }
3452
3498
  /**
3453
3499
  * Non-empty URL-safe {@link String}.
3454
3500
  *
@@ -3460,6 +3506,14 @@ export interface RegexError<Name extends TypeName = TypeName> extends TypeError<
3460
3506
  */
3461
3507
  export declare const UrlSafeString: BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "UrlSafeString", RegexError<"UrlSafeString">>;
3462
3508
  export type UrlSafeString = typeof UrlSafeString.Output;
3509
+ /**
3510
+ * Error returned when a string is not valid {@link Base64Url} text.
3511
+ *
3512
+ * @group String
3513
+ */
3514
+ export interface Base64UrlError extends TypeError<"Base64Url"> {
3515
+ readonly value: string;
3516
+ }
3463
3517
  /**
3464
3518
  * Base64Url text without padding.
3465
3519
  *
@@ -3470,14 +3524,6 @@ export type UrlSafeString = typeof UrlSafeString.Output;
3470
3524
  */
3471
3525
  export declare const Base64Url: BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Base64Url", Base64UrlError>;
3472
3526
  export type Base64Url = typeof Base64Url.Output;
3473
- /**
3474
- * Error returned when a string is not valid {@link Base64Url} text.
3475
- *
3476
- * @group String
3477
- */
3478
- export interface Base64UrlError extends TypeError<"Base64Url"> {
3479
- readonly value: string;
3480
- }
3481
3527
  /**
3482
3528
  * Converts bytes to {@link Base64Url}.
3483
3529
  *
@@ -3518,6 +3564,14 @@ export declare const uint8ArrayToBase64Url: (bytes: Uint8Array) => Base64Url;
3518
3564
  * @group String
3519
3565
  */
3520
3566
  export declare const base64UrlToUint8Array: (value: Base64Url) => Uint8Array;
3567
+ /**
3568
+ * Error returned when a string is not a valid {@link Name}.
3569
+ *
3570
+ * @group String
3571
+ */
3572
+ export interface NameError extends TypeError<"Name"> {
3573
+ readonly value: string;
3574
+ }
3521
3575
  /**
3522
3576
  * A non-empty file-system-safe and URL-safe token of at most 64 UTF-16 code
3523
3577
  * units.
@@ -3531,14 +3585,6 @@ export declare const base64UrlToUint8Array: (value: Base64Url) => Uint8Array;
3531
3585
  */
3532
3586
  export declare const Name: BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "UrlSafeString", RegexError<"UrlSafeString">>, "Name", NameError>;
3533
3587
  export type Name = typeof Name.Output;
3534
- /**
3535
- * Error returned when a string is not a valid {@link Name}.
3536
- *
3537
- * @group String
3538
- */
3539
- export interface NameError extends TypeError<"Name"> {
3540
- readonly value: string;
3541
- }
3542
3588
  /**
3543
3589
  * Stable valid {@link Name} for tests and internal fixtures.
3544
3590
  *
@@ -3552,13 +3598,6 @@ export declare const testName: string & Brand<"UrlSafeString"> & Brand<"Name">;
3552
3598
  */
3553
3599
  export declare const SimplePassword: BrandType<BrandType<BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Trimmed", TrimmedError>, "MaxLength64", MaxLengthError<64>>, "MinLength8", MinLengthError<8>>, "SimplePassword", never>;
3554
3600
  export type SimplePassword = typeof SimplePassword.Output;
3555
- /**
3556
- * A valid English BIP39 mnemonic.
3557
- *
3558
- * @group String
3559
- */
3560
- export declare const Mnemonic: BrandType<BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Trimmed", TrimmedError>, "MinLength1", MinLengthError<1>>, "Mnemonic", MnemonicError>;
3561
- export type Mnemonic = typeof Mnemonic.Output;
3562
3601
  /**
3563
3602
  * Error returned when a string is not a valid English BIP39 {@link Mnemonic}.
3564
3603
  *
@@ -3567,6 +3606,13 @@ export type Mnemonic = typeof Mnemonic.Output;
3567
3606
  export interface MnemonicError extends TypeError<"Mnemonic"> {
3568
3607
  readonly value: string;
3569
3608
  }
3609
+ /**
3610
+ * A valid English BIP39 mnemonic.
3611
+ *
3612
+ * @group String
3613
+ */
3614
+ export declare const Mnemonic: BrandType<BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Trimmed", TrimmedError>, "MinLength1", MinLengthError<1>>, "Mnemonic", MnemonicError>;
3615
+ export type Mnemonic = typeof Mnemonic.Output;
3570
3616
  /**
3571
3617
  * Evolu Id: 16 bytes encoded as a 22-character {@link Base64Url}.
3572
3618
  *
@@ -3585,14 +3631,6 @@ export interface MnemonicError extends TypeError<"Mnemonic"> {
3585
3631
  */
3586
3632
  export declare const Id: BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Id", IdError>;
3587
3633
  export type Id = typeof Id.Output;
3588
- /**
3589
- * Error returned when a string is not a valid {@link Id}.
3590
- *
3591
- * @group String
3592
- */
3593
- export interface IdError extends TypeError<"Id"> {
3594
- readonly value: string;
3595
- }
3596
3634
  /**
3597
3635
  * Creates a cryptographically random {@link Id}.
3598
3636
  *
@@ -3681,6 +3719,31 @@ export declare const createIdFromString: <B extends string = never>(value: strin
3681
3719
  * @group String
3682
3720
  */
3683
3721
  export declare const createIdAsUuidv7: <B extends string = never>(deps: RandomBytesDep & TimeDep, ..._validation: IdBrandValidation<B>) => CreatedId<B>;
3722
+ /**
3723
+ * The {@link Type} returned by {@link id} for one table.
3724
+ *
3725
+ * @group String
3726
+ */
3727
+ export interface TableId<Table extends TypeName> extends Type<"TableId", string, Id & Brand<Table>, TableIdError<Table>, typeof String, TableIdError<Table> | InferErrors<typeof String>, ChildCustomFrom<typeof String, Id & Brand<Table>, TableIdError<Table>>, CanonicalInputForChild<typeof String, Id & Brand<Table>>, IdentityEncodingOf<typeof String>> {
3728
+ readonly table: Table;
3729
+ }
3730
+ /**
3731
+ * Error returned when a string is not a valid {@link Id} for the expected table.
3732
+ *
3733
+ * @group String
3734
+ */
3735
+ export interface TableIdError<Table extends TypeName = TypeName> extends TypeError<"TableId"> {
3736
+ readonly table: Table;
3737
+ readonly value: string;
3738
+ }
3739
+ /**
3740
+ * Error returned when a string is not a valid {@link Id}.
3741
+ *
3742
+ * @group String
3743
+ */
3744
+ export interface IdError extends TypeError<"Id"> {
3745
+ readonly value: string;
3746
+ }
3684
3747
  /**
3685
3748
  * Table-specific {@link Id} Type.
3686
3749
  *
@@ -3704,23 +3767,6 @@ export declare const createIdAsUuidv7: <B extends string = never>(deps: RandomBy
3704
3767
  * @group String
3705
3768
  */
3706
3769
  export declare const id: <Table extends TypeName>(table: ValidateTableName<Table>) => TableId<Table>;
3707
- /**
3708
- * The {@link Type} returned by {@link id} for one table.
3709
- *
3710
- * @group String
3711
- */
3712
- export interface TableId<Table extends TypeName> extends Type<"TableId", string, Id & Brand<Table>, TableIdError<Table>, typeof String, TableIdError<Table> | InferErrors<typeof String>, ChildCustomFrom<typeof String, Id & Brand<Table>, TableIdError<Table>>, CanonicalInputForChild<typeof String, Id & Brand<Table>>, IdentityEncodingOf<typeof String>> {
3713
- readonly table: Table;
3714
- }
3715
- /**
3716
- * Error returned when a string is not a valid {@link Id} for the expected table.
3717
- *
3718
- * @group String
3719
- */
3720
- export interface TableIdError<Table extends TypeName = TypeName> extends TypeError<"TableId"> {
3721
- readonly table: Table;
3722
- readonly value: string;
3723
- }
3724
3770
  type ValidateTableName<Table extends TypeName> = IsTypeNameUnion<Table> extends false ? {} extends Readonly<Record<Table, never>> ? ConcreteTableNameError : Table : ConcreteTableNameError;
3725
3771
  type ConcreteTableNameError = CompileTimeError<"TableId", "Table name must be one concrete literal, not a union or widened TypeName.">;
3726
3772
  type CreatedId<B extends string> = [B] extends [never] ? Id : Id & Brand<B>;
@@ -3783,13 +3829,6 @@ export declare const idToIdBytes: (value: Id) => IdBytes;
3783
3829
  * @group String
3784
3830
  */
3785
3831
  export declare const idBytesToId: (value: IdBytes) => Id;
3786
- /**
3787
- * Decimal string representation of a signed {@link Int64}.
3788
- *
3789
- * @group Number
3790
- */
3791
- export declare const Int64String: BrandType<BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Trimmed", TrimmedError>, "MinLength1", MinLengthError<1>>, "Int64String", Int64StringError>;
3792
- export type Int64String = typeof Int64String.Output;
3793
3832
  /**
3794
3833
  * Error returned when a string is not a canonical {@link Int64String}.
3795
3834
  *
@@ -3798,6 +3837,13 @@ export type Int64String = typeof Int64String.Output;
3798
3837
  export interface Int64StringError extends TypeError<"Int64String"> {
3799
3838
  readonly value: string;
3800
3839
  }
3840
+ /**
3841
+ * Decimal string representation of a signed {@link Int64}.
3842
+ *
3843
+ * @group Number
3844
+ */
3845
+ export declare const Int64String: BrandType<BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Trimmed", TrimmedError>, "MinLength1", MinLengthError<1>>, "Int64String", Int64StringError>;
3846
+ export type Int64String = typeof Int64String.Output;
3801
3847
  /**
3802
3848
  * Transforms an {@link Int64String} into an {@link Int64}.
3803
3849
  *
@@ -3826,6 +3872,14 @@ export interface Int64StringError extends TypeError<"Int64String"> {
3826
3872
  * @group Number
3827
3873
  */
3828
3874
  export declare const Int64FromInt64String: TransformType<BrandType<BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Trimmed", TrimmedError>, "MinLength1", MinLengthError<1>>, "Int64String", Int64StringError>, BrandType<Type<"BigInt", bigint, bigint, TypeOfError<"BigInt">, null, TypeOfError<"BigInt">, never, bigint, true>, "Int64", Int64Error>, "Int64FromInt64String", never, string & Brand<"Trimmed"> & Brand<"MinLength1"> & Brand<"Int64String">>;
3875
+ /**
3876
+ * Error returned when {@link nonNegative} rejects a number.
3877
+ *
3878
+ * @group Number
3879
+ */
3880
+ export interface NonNegativeError extends TypeError<"NonNegative"> {
3881
+ readonly value: number;
3882
+ }
3829
3883
  /**
3830
3884
  * Number {@link Brand} requiring a value greater than or equal to zero.
3831
3885
  *
@@ -3843,20 +3897,20 @@ export declare const Int64FromInt64String: TransformType<BrandType<BrandType<Bra
3843
3897
  */
3844
3898
  export declare const nonNegative: BrandFactory<"NonNegative", number, NonNegativeError>;
3845
3899
  /**
3846
- * Error returned when {@link nonNegative} rejects a number.
3900
+ * Non-negative {@link Number}.
3847
3901
  *
3848
3902
  * @group Number
3849
3903
  */
3850
- export interface NonNegativeError extends TypeError<"NonNegative"> {
3851
- readonly value: number;
3852
- }
3904
+ export declare const NonNegativeNumber: BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonNegative", NonNegativeError>;
3905
+ export type NonNegativeNumber = typeof NonNegativeNumber.Output;
3853
3906
  /**
3854
- * Non-negative {@link Number}.
3907
+ * Error returned when {@link positive} rejects a number.
3855
3908
  *
3856
3909
  * @group Number
3857
3910
  */
3858
- export declare const NonNegativeNumber: BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonNegative", NonNegativeError>;
3859
- export type NonNegativeNumber = typeof NonNegativeNumber.Output;
3911
+ export interface PositiveError extends TypeError<"Positive"> {
3912
+ readonly value: number;
3913
+ }
3860
3914
  /**
3861
3915
  * Number {@link Brand} requiring a value greater than zero.
3862
3916
  *
@@ -3873,14 +3927,6 @@ export type NonNegativeNumber = typeof NonNegativeNumber.Output;
3873
3927
  * @group Number
3874
3928
  */
3875
3929
  export declare const positive: BrandFactory<"Positive", number, PositiveError>;
3876
- /**
3877
- * Error returned when {@link positive} rejects a number.
3878
- *
3879
- * @group Number
3880
- */
3881
- export interface PositiveError extends TypeError<"Positive"> {
3882
- readonly value: number;
3883
- }
3884
3930
  /**
3885
3931
  * Positive {@link Number}.
3886
3932
  *
@@ -3891,6 +3937,14 @@ export interface PositiveError extends TypeError<"Positive"> {
3891
3937
  */
3892
3938
  export declare const PositiveNumber: BrandType<BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonNegative", NonNegativeError>, "Positive", PositiveError>;
3893
3939
  export type PositiveNumber = typeof PositiveNumber.Output;
3940
+ /**
3941
+ * Error returned when {@link nonPositive} rejects a number.
3942
+ *
3943
+ * @group Number
3944
+ */
3945
+ export interface NonPositiveError extends TypeError<"NonPositive"> {
3946
+ readonly value: number;
3947
+ }
3894
3948
  /**
3895
3949
  * Number {@link Brand} requiring a value less than or equal to zero.
3896
3950
  *
@@ -3908,20 +3962,20 @@ export type PositiveNumber = typeof PositiveNumber.Output;
3908
3962
  */
3909
3963
  export declare const nonPositive: BrandFactory<"NonPositive", number, NonPositiveError>;
3910
3964
  /**
3911
- * Error returned when {@link nonPositive} rejects a number.
3965
+ * Non-positive {@link Number}.
3912
3966
  *
3913
3967
  * @group Number
3914
3968
  */
3915
- export interface NonPositiveError extends TypeError<"NonPositive"> {
3916
- readonly value: number;
3917
- }
3969
+ export declare const NonPositiveNumber: BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonPositive", NonPositiveError>;
3970
+ export type NonPositiveNumber = typeof NonPositiveNumber.Output;
3918
3971
  /**
3919
- * Non-positive {@link Number}.
3972
+ * Error returned when {@link negative} rejects a number.
3920
3973
  *
3921
3974
  * @group Number
3922
3975
  */
3923
- export declare const NonPositiveNumber: BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonPositive", NonPositiveError>;
3924
- export type NonPositiveNumber = typeof NonPositiveNumber.Output;
3976
+ export interface NegativeError extends TypeError<"Negative"> {
3977
+ readonly value: number;
3978
+ }
3925
3979
  /**
3926
3980
  * Number {@link Brand} requiring a value less than zero.
3927
3981
  *
@@ -3938,14 +3992,6 @@ export type NonPositiveNumber = typeof NonPositiveNumber.Output;
3938
3992
  * @group Number
3939
3993
  */
3940
3994
  export declare const negative: BrandFactory<"Negative", number, NegativeError>;
3941
- /**
3942
- * Error returned when {@link negative} rejects a number.
3943
- *
3944
- * @group Number
3945
- */
3946
- export interface NegativeError extends TypeError<"Negative"> {
3947
- readonly value: number;
3948
- }
3949
3995
  /**
3950
3996
  * Negative {@link Number}.
3951
3997
  *
@@ -3956,6 +4002,14 @@ export interface NegativeError extends TypeError<"Negative"> {
3956
4002
  */
3957
4003
  export declare const NegativeNumber: BrandType<BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonPositive", NonPositiveError>, "Negative", NegativeError>;
3958
4004
  export type NegativeNumber = typeof NegativeNumber.Output;
4005
+ /**
4006
+ * Error returned when {@link nonNaN} rejects `NaN`.
4007
+ *
4008
+ * @group Number
4009
+ */
4010
+ export interface NonNaNError extends TypeError<"NonNaN"> {
4011
+ readonly value: number;
4012
+ }
3959
4013
  /**
3960
4014
  * Number {@link Brand} requiring a value other than `NaN`.
3961
4015
  *
@@ -3972,14 +4026,6 @@ export type NegativeNumber = typeof NegativeNumber.Output;
3972
4026
  * @group Number
3973
4027
  */
3974
4028
  export declare const nonNaN: BrandFactory<"NonNaN", number, NonNaNError>;
3975
- /**
3976
- * Error returned when {@link nonNaN} rejects `NaN`.
3977
- *
3978
- * @group Number
3979
- */
3980
- export interface NonNaNError extends TypeError<"NonNaN"> {
3981
- readonly value: number;
3982
- }
3983
4029
  /**
3984
4030
  * {@link Number} other than `NaN`; infinities are allowed.
3985
4031
  *
@@ -3992,6 +4038,14 @@ export interface NonNaNError extends TypeError<"NonNaN"> {
3992
4038
  */
3993
4039
  export declare const NonNaNNumber: BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonNaN", NonNaNError>;
3994
4040
  export type NonNaNNumber = typeof NonNaNNumber.Output;
4041
+ /**
4042
+ * Error returned when {@link finite} rejects a non-finite number.
4043
+ *
4044
+ * @group Number
4045
+ */
4046
+ export interface FiniteError extends TypeError<"Finite"> {
4047
+ readonly value: number;
4048
+ }
3995
4049
  /**
3996
4050
  * Number {@link Brand} requiring a finite value.
3997
4051
  *
@@ -4008,14 +4062,6 @@ export type NonNaNNumber = typeof NonNaNNumber.Output;
4008
4062
  * @group Number
4009
4063
  */
4010
4064
  export declare const finite: BrandFactory<"Finite", number, FiniteError>;
4011
- /**
4012
- * Error returned when {@link finite} rejects a non-finite number.
4013
- *
4014
- * @group Number
4015
- */
4016
- export interface FiniteError extends TypeError<"Finite"> {
4017
- readonly value: number;
4018
- }
4019
4065
  /**
4020
4066
  * Finite {@link Number}.
4021
4067
  *
@@ -4037,6 +4083,14 @@ export type NonNegativeFiniteNumber = typeof NonNegativeFiniteNumber.Output;
4037
4083
  */
4038
4084
  export declare const PositiveFiniteNumber: BrandType<BrandType<BrandType<BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonNaN", NonNaNError>, "Finite", FiniteError>, "NonNegative", NonNegativeError>, "Positive", PositiveError>;
4039
4085
  export type PositiveFiniteNumber = typeof PositiveFiniteNumber.Output;
4086
+ /**
4087
+ * Error returned when {@link int} rejects a number that is not a safe integer.
4088
+ *
4089
+ * @group Number
4090
+ */
4091
+ export interface IntError extends TypeError<"Int"> {
4092
+ readonly value: number;
4093
+ }
4040
4094
  /**
4041
4095
  * Safe integer {@link Brand}.
4042
4096
  *
@@ -4074,14 +4128,6 @@ export type PositiveFiniteNumber = typeof PositiveFiniteNumber.Output;
4074
4128
  * @group Number
4075
4129
  */
4076
4130
  export declare const int: BrandFactory<"Int", number, IntError>;
4077
- /**
4078
- * Error returned when {@link int} rejects a number that is not a safe integer.
4079
- *
4080
- * @group Number
4081
- */
4082
- export interface IntError extends TypeError<"Int"> {
4083
- readonly value: number;
4084
- }
4085
4131
  /**
4086
4132
  * Safe integer {@link FiniteNumber}.
4087
4133
  *
@@ -4187,6 +4233,15 @@ export type NonPositiveInt = typeof NonPositiveInt.Output;
4187
4233
  */
4188
4234
  export declare const NegativeInt: BrandType<BrandType<BrandType<BrandType<BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonNaN", NonNaNError>, "Finite", FiniteError>, "Int", IntError>, "NonPositive", NonPositiveError>, "Negative", NegativeError>;
4189
4235
  export type NegativeInt = typeof NegativeInt.Output;
4236
+ /**
4237
+ * Error returned when {@link greaterThan} rejects a number.
4238
+ *
4239
+ * @group Number
4240
+ */
4241
+ export interface GreaterThanError<Min extends number = number> extends TypeError<`GreaterThan${Min}`> {
4242
+ readonly value: number;
4243
+ readonly min: Min;
4244
+ }
4190
4245
  /**
4191
4246
  * Number {@link Brand} requiring a value greater than `min`.
4192
4247
  *
@@ -4204,11 +4259,11 @@ export type NegativeInt = typeof NegativeInt.Output;
4204
4259
  */
4205
4260
  export declare const greaterThan: <Min extends number>(min: ValidateBrandFactoryNumber<Min>) => BrandFactory<`GreaterThan${Min}`, number, GreaterThanError<Min>>;
4206
4261
  /**
4207
- * Error returned when {@link greaterThan} rejects a number.
4262
+ * Error returned when {@link greaterThanOrEqualTo} rejects a number.
4208
4263
  *
4209
4264
  * @group Number
4210
4265
  */
4211
- export interface GreaterThanError<Min extends number = number> extends TypeError<`GreaterThan${Min}`> {
4266
+ export interface GreaterThanOrEqualToError<Min extends number = number> extends TypeError<`GreaterThanOrEqualTo${Min}`> {
4212
4267
  readonly value: number;
4213
4268
  readonly min: Min;
4214
4269
  }
@@ -4229,13 +4284,13 @@ export interface GreaterThanError<Min extends number = number> extends TypeError
4229
4284
  */
4230
4285
  export declare const greaterThanOrEqualTo: <Min extends number>(min: ValidateBrandFactoryNumber<Min>) => BrandFactory<`GreaterThanOrEqualTo${Min}`, number, GreaterThanOrEqualToError<Min>>;
4231
4286
  /**
4232
- * Error returned when {@link greaterThanOrEqualTo} rejects a number.
4287
+ * Error returned when {@link lessThan} rejects a number.
4233
4288
  *
4234
4289
  * @group Number
4235
4290
  */
4236
- export interface GreaterThanOrEqualToError<Min extends number = number> extends TypeError<`GreaterThanOrEqualTo${Min}`> {
4291
+ export interface LessThanError<Max extends number = number> extends TypeError<`LessThan${Max}`> {
4237
4292
  readonly value: number;
4238
- readonly min: Min;
4293
+ readonly max: Max;
4239
4294
  }
4240
4295
  /**
4241
4296
  * Number {@link Brand} requiring a value less than `max`.
@@ -4254,21 +4309,21 @@ export interface GreaterThanOrEqualToError<Min extends number = number> extends
4254
4309
  */
4255
4310
  export declare const lessThan: <Max extends number>(max: ValidateBrandFactoryNumber<Max>) => BrandFactory<`LessThan${Max}`, number, LessThanError<Max>>;
4256
4311
  /**
4257
- * Error returned when {@link lessThan} rejects a number.
4312
+ * A person's age as a {@link NonNegativeInt} less than 200.
4258
4313
  *
4259
4314
  * @group Number
4260
4315
  */
4261
- export interface LessThanError<Max extends number = number> extends TypeError<`LessThan${Max}`> {
4262
- readonly value: number;
4263
- readonly max: Max;
4264
- }
4316
+ export declare const Age: BrandType<BrandType<BrandType<BrandType<BrandType<BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonNaN", NonNaNError>, "Finite", FiniteError>, "Int", IntError>, "NonNegative", NonNegativeError>, "LessThan200", LessThanError<200>>, "Age", never>;
4317
+ export type Age = typeof Age.Output;
4265
4318
  /**
4266
- * A person's age as a {@link NonNegativeInt} less than 200.
4319
+ * Error returned when {@link lessThanOrEqualTo} rejects a number.
4267
4320
  *
4268
4321
  * @group Number
4269
4322
  */
4270
- export declare const Age: BrandType<BrandType<BrandType<BrandType<BrandType<BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonNaN", NonNaNError>, "Finite", FiniteError>, "Int", IntError>, "NonNegative", NonNegativeError>, "LessThan200", LessThanError<200>>, "Age", never>;
4271
- export type Age = typeof Age.Output;
4323
+ export interface LessThanOrEqualToError<Max extends number = number> extends TypeError<`LessThanOrEqualTo${Max}`> {
4324
+ readonly value: number;
4325
+ readonly max: Max;
4326
+ }
4272
4327
  /**
4273
4328
  * Number {@link Brand} requiring a value less than or equal to `max`.
4274
4329
  *
@@ -4285,15 +4340,6 @@ export type Age = typeof Age.Output;
4285
4340
  * @group Number
4286
4341
  */
4287
4342
  export declare const lessThanOrEqualTo: <Max extends number>(max: ValidateBrandFactoryNumber<Max>) => BrandFactory<`LessThanOrEqualTo${Max}`, number, LessThanOrEqualToError<Max>>;
4288
- /**
4289
- * Error returned when {@link lessThanOrEqualTo} rejects a number.
4290
- *
4291
- * @group Number
4292
- */
4293
- export interface LessThanOrEqualToError<Max extends number = number> extends TypeError<`LessThanOrEqualTo${Max}`> {
4294
- readonly value: number;
4295
- readonly max: Max;
4296
- }
4297
4343
  /**
4298
4344
  * A TCP or UDP port as an integer from zero through 65535, inclusive.
4299
4345
  *
@@ -4352,6 +4398,14 @@ export declare const PortFromString: TransformType<TransformType<Type<"String",
4352
4398
  */
4353
4399
  export declare const Ratio: BrandType<BrandType<BrandType<BrandType<BrandType<Type<"Number", number, number, TypeOfError<"Number">, null, TypeOfError<"Number">, never, number, true>, "NonNaN", NonNaNError>, "Finite", FiniteError>, "NonNegative", NonNegativeError>, "LessThanOrEqualTo1", LessThanOrEqualToError<1>>, "Ratio", never>;
4354
4400
  export type Ratio = typeof Ratio.Output;
4401
+ /**
4402
+ * Error returned when a string is not a canonical {@link DecimalString}.
4403
+ *
4404
+ * @group Number
4405
+ */
4406
+ export interface DecimalStringError extends TypeError<"DecimalString"> {
4407
+ readonly value: string;
4408
+ }
4355
4409
  /**
4356
4410
  * Canonical string representation of a signed base-10 decimal value.
4357
4411
  *
@@ -4406,11 +4460,11 @@ export type Ratio = typeof Ratio.Output;
4406
4460
  export declare const DecimalString: BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "DecimalString", DecimalStringError>;
4407
4461
  export type DecimalString = typeof DecimalString.Output;
4408
4462
  /**
4409
- * Error returned when a string is not a canonical {@link DecimalString}.
4463
+ * Error returned when {@link nonNegativeDecimalString} rejects a decimal string.
4410
4464
  *
4411
4465
  * @group Number
4412
4466
  */
4413
- export interface DecimalStringError extends TypeError<"DecimalString"> {
4467
+ export interface NonNegativeDecimalStringError extends TypeError<"NonNegativeDecimalString"> {
4414
4468
  readonly value: string;
4415
4469
  }
4416
4470
  /**
@@ -4434,20 +4488,20 @@ export interface DecimalStringError extends TypeError<"DecimalString"> {
4434
4488
  */
4435
4489
  export declare const nonNegativeDecimalString: BrandFactory<"NonNegativeDecimalString", DecimalString, NonNegativeDecimalStringError>;
4436
4490
  /**
4437
- * Error returned when {@link nonNegativeDecimalString} rejects a decimal string.
4491
+ * Non-negative {@link DecimalString}.
4438
4492
  *
4439
4493
  * @group Number
4440
4494
  */
4441
- export interface NonNegativeDecimalStringError extends TypeError<"NonNegativeDecimalString"> {
4442
- readonly value: string;
4443
- }
4495
+ export declare const NonNegativeDecimalString: BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "DecimalString", DecimalStringError>, "NonNegativeDecimalString", NonNegativeDecimalStringError>;
4496
+ export type NonNegativeDecimalString = typeof NonNegativeDecimalString.Output;
4444
4497
  /**
4445
- * Non-negative {@link DecimalString}.
4498
+ * Error returned when {@link positiveDecimalString} rejects a decimal string.
4446
4499
  *
4447
4500
  * @group Number
4448
4501
  */
4449
- export declare const NonNegativeDecimalString: BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "DecimalString", DecimalStringError>, "NonNegativeDecimalString", NonNegativeDecimalStringError>;
4450
- export type NonNegativeDecimalString = typeof NonNegativeDecimalString.Output;
4502
+ export interface PositiveDecimalStringError extends TypeError<"PositiveDecimalString"> {
4503
+ readonly value: string;
4504
+ }
4451
4505
  /**
4452
4506
  * {@link DecimalString} Brand requiring a value greater than zero.
4453
4507
  *
@@ -4468,14 +4522,6 @@ export type NonNegativeDecimalString = typeof NonNegativeDecimalString.Output;
4468
4522
  * @group Number
4469
4523
  */
4470
4524
  export declare const positiveDecimalString: BrandFactory<"PositiveDecimalString", DecimalString, PositiveDecimalStringError>;
4471
- /**
4472
- * Error returned when {@link positiveDecimalString} rejects a decimal string.
4473
- *
4474
- * @group Number
4475
- */
4476
- export interface PositiveDecimalStringError extends TypeError<"PositiveDecimalString"> {
4477
- readonly value: string;
4478
- }
4479
4525
  /**
4480
4526
  * Positive {@link DecimalString}.
4481
4527
  *
@@ -4486,6 +4532,14 @@ export interface PositiveDecimalStringError extends TypeError<"PositiveDecimalSt
4486
4532
  */
4487
4533
  export declare const PositiveDecimalString: BrandType<BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "DecimalString", DecimalStringError>, "NonNegativeDecimalString", NonNegativeDecimalStringError>, "PositiveDecimalString", PositiveDecimalStringError>;
4488
4534
  export type PositiveDecimalString = typeof PositiveDecimalString.Output;
4535
+ /**
4536
+ * Error returned when {@link nonPositiveDecimalString} rejects a decimal string.
4537
+ *
4538
+ * @group Number
4539
+ */
4540
+ export interface NonPositiveDecimalStringError extends TypeError<"NonPositiveDecimalString"> {
4541
+ readonly value: string;
4542
+ }
4489
4543
  /**
4490
4544
  * {@link DecimalString} Brand requiring a value less than or equal to zero.
4491
4545
  *
@@ -4507,20 +4561,20 @@ export type PositiveDecimalString = typeof PositiveDecimalString.Output;
4507
4561
  */
4508
4562
  export declare const nonPositiveDecimalString: BrandFactory<"NonPositiveDecimalString", DecimalString, NonPositiveDecimalStringError>;
4509
4563
  /**
4510
- * Error returned when {@link nonPositiveDecimalString} rejects a decimal string.
4564
+ * Non-positive {@link DecimalString}.
4511
4565
  *
4512
4566
  * @group Number
4513
4567
  */
4514
- export interface NonPositiveDecimalStringError extends TypeError<"NonPositiveDecimalString"> {
4515
- readonly value: string;
4516
- }
4568
+ export declare const NonPositiveDecimalString: BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "DecimalString", DecimalStringError>, "NonPositiveDecimalString", NonPositiveDecimalStringError>;
4569
+ export type NonPositiveDecimalString = typeof NonPositiveDecimalString.Output;
4517
4570
  /**
4518
- * Non-positive {@link DecimalString}.
4571
+ * Error returned when {@link negativeDecimalString} rejects a decimal string.
4519
4572
  *
4520
4573
  * @group Number
4521
4574
  */
4522
- export declare const NonPositiveDecimalString: BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "DecimalString", DecimalStringError>, "NonPositiveDecimalString", NonPositiveDecimalStringError>;
4523
- export type NonPositiveDecimalString = typeof NonPositiveDecimalString.Output;
4575
+ export interface NegativeDecimalStringError extends TypeError<"NegativeDecimalString"> {
4576
+ readonly value: string;
4577
+ }
4524
4578
  /**
4525
4579
  * {@link DecimalString} Brand requiring a value less than zero.
4526
4580
  *
@@ -4541,14 +4595,6 @@ export type NonPositiveDecimalString = typeof NonPositiveDecimalString.Output;
4541
4595
  * @group Number
4542
4596
  */
4543
4597
  export declare const negativeDecimalString: BrandFactory<"NegativeDecimalString", DecimalString, NegativeDecimalStringError>;
4544
- /**
4545
- * Error returned when {@link negativeDecimalString} rejects a decimal string.
4546
- *
4547
- * @group Number
4548
- */
4549
- export interface NegativeDecimalStringError extends TypeError<"NegativeDecimalString"> {
4550
- readonly value: string;
4551
- }
4552
4598
  /**
4553
4599
  * Negative {@link DecimalString}.
4554
4600
  *
@@ -4559,6 +4605,15 @@ export interface NegativeDecimalStringError extends TypeError<"NegativeDecimalSt
4559
4605
  */
4560
4606
  export declare const NegativeDecimalString: BrandType<BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "DecimalString", DecimalStringError>, "NonPositiveDecimalString", NonPositiveDecimalStringError>, "NegativeDecimalString", NegativeDecimalStringError>;
4561
4607
  export type NegativeDecimalString = typeof NegativeDecimalString.Output;
4608
+ /**
4609
+ * Error returned when {@link multipleOf} rejects a number.
4610
+ *
4611
+ * @group Number
4612
+ */
4613
+ export interface MultipleOfError<Divisor extends string = string> extends TypeError<`MultipleOf${Divisor}`> {
4614
+ readonly value: number;
4615
+ readonly divisor: Divisor;
4616
+ }
4562
4617
  /**
4563
4618
  * Number {@link Brand} requiring an exact decimal multiple of `divisor`.
4564
4619
  *
@@ -4606,15 +4661,6 @@ export type NegativeDecimalString = typeof NegativeDecimalString.Output;
4606
4661
  * @group Number
4607
4662
  */
4608
4663
  export declare const multipleOf: <const Divisor extends string>(divisor: ValidateMultipleOfDivisor<Divisor>) => BrandFactory<`MultipleOf${Divisor}`, number, MultipleOfError<Divisor>>;
4609
- /**
4610
- * Error returned when {@link multipleOf} rejects a number.
4611
- *
4612
- * @group Number
4613
- */
4614
- export interface MultipleOfError<Divisor extends string = string> extends TypeError<`MultipleOf${Divisor}`> {
4615
- readonly value: number;
4616
- readonly divisor: Divisor;
4617
- }
4618
4664
  type ValidateMultipleOfDivisor<Divisor extends string> = IsUnion<Divisor> extends false ? string extends Divisor ? InvalidMultipleOfDivisor<Divisor> : IsCanonicalPositiveDecimalString<Divisor> extends true ? Divisor : InvalidMultipleOfDivisor<Divisor> : InvalidMultipleOfDivisor<Divisor>;
4619
4665
  type IsCanonicalPositiveDecimalString<Value extends string> = Value extends `${infer Integer}.${infer Fraction}` ? IsCanonicalNonNegativeIntegerString<Integer> extends true ? IsCanonicalPositiveFractionString<Fraction> : false : IsCanonicalPositiveIntegerString<Value>;
4620
4666
  type IsCanonicalNonNegativeIntegerString<Value extends string> = Value extends "0" ? true : IsCanonicalPositiveIntegerString<Value>;
@@ -4623,6 +4669,16 @@ type IsCanonicalPositiveFractionString<Value extends string> = Value extends `${
4623
4669
  type IsDecimalDigits<Value extends string> = Value extends "" ? true : Value extends `${Digit}${infer Rest}` ? IsDecimalDigits<Rest> : false;
4624
4670
  type InvalidMultipleOfDivisor<Divisor extends string> = Divisor & Readonly<Record<MultipleOfDivisorError, never>>;
4625
4671
  type MultipleOfDivisorError = CompileTimeError<"MultipleOf", 'Divisor must be one canonical positive decimal string literal such as "0.1".'>;
4672
+ /**
4673
+ * Error returned when {@link between} rejects a number.
4674
+ *
4675
+ * @group Number
4676
+ */
4677
+ export interface BetweenError<Min extends number = number, Max extends number = number> extends TypeError<`Between${Min}-${Max}`> {
4678
+ readonly value: number;
4679
+ readonly min: Min;
4680
+ readonly max: Max;
4681
+ }
4626
4682
  /**
4627
4683
  * Number {@link Brand} requiring a value within an inclusive range.
4628
4684
  *
@@ -4640,125 +4696,51 @@ type MultipleOfDivisorError = CompileTimeError<"MultipleOf", 'Divisor must be on
4640
4696
  */
4641
4697
  export declare const between: <Min extends number, Max extends number>(min: ValidateBrandFactoryNumber<Min>, max: ValidateBrandFactoryNumber<Max>) => BrandFactory<`Between${Min}-${Max}`, number, BetweenError<Min, Max>>;
4642
4698
  /**
4643
- * Error returned when {@link between} rejects a number.
4699
+ * The homogeneous readonly-array {@link Type} returned by {@link array}.
4644
4700
  *
4645
- * @group Number
4701
+ * @group Collection
4646
4702
  */
4647
- export interface BetweenError<Min extends number = number, Max extends number = number> extends TypeError<`Between${Min}-${Max}`> {
4648
- readonly value: number;
4649
- readonly min: Min;
4650
- readonly max: Max;
4703
+ export interface ArrayType<ElementType extends TypeNode> extends Type<"Array", ReadonlyArray<ElementType["Input"]>, ReadonlyArray<ElementType["Output"]>, ArrayNodeError<ElementType>, ArrayParent<ElementType>, ArrayError<InferErrors<ElementType>>, ArrayCustomFrom<ElementType>, ReadonlyArray<CanonicalInputOf<ElementType>>, AllTypesUseIdentityEncoding<ElementType>> {
4704
+ readonly [reflectedTypesSymbol]?: ElementType;
4705
+ readonly element: ElementType;
4651
4706
  }
4652
4707
  /**
4653
- * Array {@link Type}.
4654
- *
4655
- * Use `array(Element)` for readonly arrays in which every element must match
4656
- * the same Type, such as arrays of IDs or labels.
4708
+ * Error returned by {@link array} for a non-array value or invalid array items.
4657
4709
  *
4658
- * `fromUnknown` validates the array and every element. By default, it returns
4659
- * the first issue. Pass `{ errors: "all" }` to collect issues across the whole
4660
- * array. Element errors identify the failing index.
4710
+ * @group Collection
4711
+ */
4712
+ export type ArrayError<Error extends TypeError = TypeError> = ArrayNotArrayError | ArrayItemsErrorValue<Error, true>;
4713
+ /**
4714
+ * Error returned when an {@link array} input is not an array.
4661
4715
  *
4662
- * `from` accepts an array of element Outputs. `from.parent` accepts an array of
4663
- * values typed as the element's parent Output. Each operation asserts its
4664
- * selected array and element boundary, then returns errors only from the
4665
- * remaining element stages. Additional suffixes move that boundary toward the
4666
- * element's root Type.
4716
+ * @group Collection
4717
+ */
4718
+ export interface ArrayNotArrayError extends TypeError<"Array"> {
4719
+ readonly reason: {
4720
+ readonly kind: "NotArray";
4721
+ readonly value: unknown;
4722
+ };
4723
+ }
4724
+ /**
4725
+ * An {@link array} error containing structural or element issues.
4667
4726
  *
4668
- * An Array must be recognized by `Array.isArray`, be dense, and have no own
4669
- * properties other than `length` and the indexed data properties from `0`
4670
- * through `length - 1`. Subclasses, custom-prototype arrays, and foreign-realm
4671
- * arrays are accepted when their own data representation is valid. Sparse
4672
- * arrays, accessor elements, and excess properties are rejected.
4727
+ * @group Collection
4728
+ */
4729
+ export type ArrayItemsError<Error extends TypeError> = ArrayItemsErrorValue<Error, true>;
4730
+ /**
4731
+ * The shape of {@link ArrayItemsError} and {@link ArrayElementsError}.
4673
4732
  *
4674
- * ### Example
4675
- *
4676
- * ```ts
4677
- * import {
4678
- * assertEqual,
4679
- * assertErr,
4680
- * assertOk,
4681
- * assertType,
4682
- * Data,
4683
- * String,
4684
- * array,
4685
- * brand,
4686
- * type Brand,
4687
- * type Result,
4688
- * } from "@evolu/common";
4689
- *
4690
- * const UserId = brand("UserId", String);
4691
- * const UserIds = array(UserId);
4692
- *
4693
- * const result = UserIds.from.parent(["ada", "grace"]);
4694
- *
4695
- * assertType<
4696
- * typeof result,
4697
- * Result<ReadonlyArray<string & Brand<"UserId">>>
4698
- * >();
4699
- * assertOk(result, ["ada", "grace"]);
4700
- * assertOk(UserIds.fromUnknown(["ada", "grace"]), ["ada", "grace"]);
4701
- *
4702
- * const invalid = UserIds.fromUnknown("ada");
4703
- * assertErr(invalid);
4704
- * assertType(Data, invalid.error);
4705
- * assertEqual(invalid.error, {
4706
- * type: "Array",
4707
- * reason: { kind: "NotArray", value: "ada" },
4708
- * });
4709
- * ```
4710
- *
4711
- * @group Collection
4712
- */
4713
- export declare const array: <ElementType extends ConcreteTypeNode>(element: ValidateElement<ElementType>) => ArrayType<ElementType>;
4714
- /**
4715
- * The homogeneous readonly-array {@link Type} returned by {@link array}.
4716
- *
4717
- * @group Collection
4718
- */
4719
- export interface ArrayType<ElementType extends TypeNode> extends Type<"Array", ReadonlyArray<ElementType["Input"]>, ReadonlyArray<ElementType["Output"]>, ArrayNodeError<ElementType>, ArrayParent<ElementType>, ArrayError<InferErrors<ElementType>>, ArrayCustomFrom<ElementType>, ReadonlyArray<CanonicalInputOf<ElementType>>, AllTypesUseIdentityEncoding<ElementType>> {
4720
- readonly [reflectedTypesSymbol]?: ElementType;
4721
- readonly element: ElementType;
4722
- }
4723
- type ArrayCustomFrom<ElementType extends TypeNode> = [
4724
- ElementType["parent"]
4725
- ] extends [TypeNode] ? ArrayFromOperation<ElementType> : never;
4726
- type ArrayFromOperation<ElementType extends TypeNode> = [
4727
- ElementType["parent"]
4728
- ] extends [infer Parent extends TypeNode] ? TypeOperationFn<"from", ReadonlyArray<ElementType["Output"]>, ReadonlyArray<ElementType["Output"]>, never> & ArrayFromParentOperations<ElementType["Output"], ElementType["Error"], Parent> : TypeOperationFn<"from", ReadonlyArray<ElementType["Output"]>, ReadonlyArray<ElementType["Output"]>, never>;
4729
- interface ArrayFromParentOperations<Output, Error extends TypeError, Boundary extends TypeNode> {
4730
- readonly parent: TypeOperationFn<"from", ReadonlyArray<Boundary["Output"]>, ReadonlyArray<Output>, ArrayElementsError<Error>> & ([Boundary["parent"]] extends [infer Parent extends TypeNode] ? ArrayFromParentOperations<Output, Error | Boundary["Error"], Parent> : unknown);
4731
- }
4732
- type ValidateElement<T extends ConcreteTypeNode> = IsUnion<T> extends false ? T : CompileTimeError<"Type", "Element must be one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
4733
- type ArrayParent<ElementType extends TypeNode> = [
4734
- ElementType["parent"]
4735
- ] extends [infer ParentElement extends TypeNode] ? ArrayType<ParentElement> : null;
4736
- type ArrayNodeError<ElementType extends TypeNode> = [
4737
- ElementType["parent"]
4738
- ] extends [TypeNode] ? ArrayElementsError<ElementType["Error"]> : ArrayError<ElementType["Error"]>;
4739
- /**
4740
- * Error returned by {@link array} for a non-array value or invalid array items.
4741
- *
4742
- * @group Collection
4743
- */
4744
- export type ArrayError<Error extends TypeError = TypeError> = ArrayNotArrayError | ArrayItemsErrorValue<Error, true>;
4745
- /**
4746
- * Error returned when an {@link array} input is not an array.
4733
+ * Structural issues are included only when `IncludeStructuralIssues` is true
4734
+ * because a typed boundary asserts the array structure.
4747
4735
  *
4748
4736
  * @group Collection
4749
4737
  */
4750
- export interface ArrayNotArrayError extends TypeError<"Array"> {
4738
+ export interface ArrayItemsErrorValue<Error extends TypeError, IncludeStructuralIssues extends boolean> extends TypeError<"Array"> {
4751
4739
  readonly reason: {
4752
- readonly kind: "NotArray";
4753
- readonly value: unknown;
4740
+ readonly kind: "Items";
4741
+ readonly issues: NonEmptyReadonlyArray<(true extends IncludeStructuralIssues ? ArrayStructuralIssue : never) | ArrayElementIssue<Error>>;
4754
4742
  };
4755
4743
  }
4756
- /**
4757
- * An {@link array} error containing structural or element issues.
4758
- *
4759
- * @group Collection
4760
- */
4761
- export type ArrayItemsError<Error extends TypeError> = ArrayItemsErrorValue<Error, true>;
4762
4744
  /**
4763
4745
  * One structural or element issue found by {@link array}.
4764
4746
  *
@@ -4792,7 +4774,6 @@ export interface ArrayExcessPropertyIssue {
4792
4774
  readonly kind: "ExcessProperty";
4793
4775
  readonly key: string | symbol;
4794
4776
  }
4795
- type ArrayStructuralIssue = ArrayHoleIssue | ArrayAccessorIssue | ArrayExcessPropertyIssue;
4796
4777
  /**
4797
4778
  * An invalid array element and its index.
4798
4779
  *
@@ -4811,34 +4792,93 @@ export type ArrayElementIssue<Error extends TypeError> = Error extends TypeError
4811
4792
  export type ArrayElementsError<Error extends TypeError> = [Error] extends [
4812
4793
  never
4813
4794
  ] ? never : ArrayItemsErrorValue<Error, false>;
4814
- interface ArrayItemsErrorValue<Error extends TypeError, IncludeStructuralIssues extends boolean> extends TypeError<"Array"> {
4815
- readonly reason: {
4816
- readonly kind: "Items";
4817
- readonly issues: NonEmptyReadonlyArray<(true extends IncludeStructuralIssues ? ArrayStructuralIssue : never) | ArrayElementIssue<Error>>;
4818
- };
4819
- }
4820
4795
  /**
4821
- * Set {@link Type} whose every element must match one Type.
4796
+ * Array {@link Type}.
4822
4797
  *
4823
- * Sets from this or another realm are accepted. A Set must have no own
4824
- * properties; its elements are validated in iteration order. Classification
4825
- * uses the realm-neutral object tag under Evolu Type's trusted JavaScript
4826
- * policy.
4798
+ * Use `array(Element)` for readonly arrays in which every element must match
4799
+ * the same Type, such as arrays of IDs or labels.
4800
+ *
4801
+ * `fromUnknown` validates the array and every element. By default, it returns
4802
+ * the first issue. Pass `{ errors: "all" }` to collect issues across the whole
4803
+ * array. Element errors identify the failing index.
4804
+ *
4805
+ * `from` accepts an array of element Outputs. `from.parent` accepts an array of
4806
+ * values typed as the element's parent Output. Each operation asserts its
4807
+ * selected array and element boundary, then returns errors only from the
4808
+ * remaining element stages. Additional suffixes move that boundary toward the
4809
+ * element's root Type.
4810
+ *
4811
+ * An Array must be recognized by `Array.isArray`, be dense, and have no own
4812
+ * properties other than `length` and the indexed data properties from `0`
4813
+ * through `length - 1`. Subclasses, custom-prototype arrays, and foreign-realm
4814
+ * arrays are accepted when their own data representation is valid. Sparse
4815
+ * arrays, accessor elements, and excess properties are rejected.
4827
4816
  *
4828
4817
  * ### Example
4829
4818
  *
4830
4819
  * ```ts
4831
- * import { assertOk, String, set } from "@evolu/common";
4820
+ * import {
4821
+ * assertEqual,
4822
+ * assertErr,
4823
+ * assertOk,
4824
+ * assertType,
4825
+ * Data,
4826
+ * String,
4827
+ * array,
4828
+ * brand,
4829
+ * type Brand,
4830
+ * type Result,
4831
+ * } from "@evolu/common";
4832
4832
  *
4833
- * const Tags = set(String);
4834
- * const tags = new Set(["local-first", "offline"]);
4833
+ * const UserId = brand("UserId", String);
4834
+ * const UserIds = array(UserId);
4835
4835
  *
4836
- * assertOk(Tags.fromUnknown(tags), tags);
4836
+ * const result = UserIds.from.parent(["ada", "grace"]);
4837
+ *
4838
+ * assertType<
4839
+ * typeof result,
4840
+ * Result<ReadonlyArray<string & Brand<"UserId">>>
4841
+ * >();
4842
+ * assertOk(result, ["ada", "grace"]);
4843
+ * assertOk(UserIds.fromUnknown(["ada", "grace"]), ["ada", "grace"]);
4844
+ *
4845
+ * const invalid = UserIds.fromUnknown("ada");
4846
+ * assertErr(invalid);
4847
+ * assertType(Data, invalid.error);
4848
+ * assertEqual(invalid.error, {
4849
+ * type: "Array",
4850
+ * reason: { kind: "NotArray", value: "ada" },
4851
+ * });
4837
4852
  * ```
4838
4853
  *
4839
4854
  * @group Collection
4840
4855
  */
4841
- export declare const set: <ElementType extends ConcreteTypeNode>(element: ValidateElement<ElementType>) => SetType<ElementType>;
4856
+ export declare const array: <ElementType extends ConcreteTypeNode>(element: ValidateElement<ElementType>) => ArrayType<ElementType>;
4857
+ type ArrayCustomFrom<ElementType extends TypeNode> = [
4858
+ ElementType["parent"]
4859
+ ] extends [TypeNode] ? ArrayFromOperation<ElementType> : never;
4860
+ type ArrayFromOperation<ElementType extends TypeNode> = [
4861
+ ElementType["parent"]
4862
+ ] extends [infer Parent extends TypeNode] ? TypeOperationFn<"from", ReadonlyArray<ElementType["Output"]>, ReadonlyArray<ElementType["Output"]>, never> & ArrayFromParentOperations<ElementType["Output"], ElementType["Error"], Parent> : TypeOperationFn<"from", ReadonlyArray<ElementType["Output"]>, ReadonlyArray<ElementType["Output"]>, never>;
4863
+ /**
4864
+ * The `.parent` suffixes of an {@link ArrayType} `from` operation.
4865
+ *
4866
+ * Each `.parent` accepts an array of the next element Output toward the root
4867
+ * and returns the element errors of every boundary it adds.
4868
+ *
4869
+ * @group Collection
4870
+ */
4871
+ export interface ArrayFromParentOperations<Output, Error extends TypeError, Boundary extends TypeNode> {
4872
+ readonly parent: TypeOperationFn<"from", ReadonlyArray<Boundary["Output"]>, ReadonlyArray<Output>, ArrayElementsError<Error>> & ([Boundary["parent"]] extends [infer Parent extends TypeNode] ? ArrayFromParentOperations<Output, Error | Boundary["Error"], Parent> : unknown);
4873
+ }
4874
+ type ValidateElement<T extends ConcreteTypeNode> = IsUnion<T> extends false ? T : CompileTimeError<"Type", "Element must be one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
4875
+ type ArrayParent<ElementType extends TypeNode> = [
4876
+ ElementType["parent"]
4877
+ ] extends [infer ParentElement extends TypeNode] ? ArrayType<ParentElement> : null;
4878
+ type ArrayNodeError<ElementType extends TypeNode> = [
4879
+ ElementType["parent"]
4880
+ ] extends [TypeNode] ? ArrayElementsError<ElementType["Error"]> : ArrayError<ElementType["Error"]>;
4881
+ type ArrayStructuralIssue = ArrayHoleIssue | ArrayAccessorIssue | ArrayExcessPropertyIssue;
4842
4882
  /**
4843
4883
  * The homogeneous readonly-set {@link Type} returned by {@link set}.
4844
4884
  *
@@ -4848,21 +4888,6 @@ export interface SetType<ElementType extends TypeNode> extends Type<"Set", Reado
4848
4888
  readonly [reflectedTypesSymbol]?: ElementType;
4849
4889
  readonly element: ElementType;
4850
4890
  }
4851
- type SetCustomFrom<ElementType extends TypeNode> = [
4852
- ElementType["parent"]
4853
- ] extends [TypeNode] ? SetFromOperation<ElementType> : never;
4854
- type SetFromOperation<ElementType extends TypeNode> = [
4855
- ElementType["parent"]
4856
- ] extends [infer Parent extends TypeNode] ? TypeOperationFn<"from", ReadonlySet<ElementType["Output"]>, ReadonlySet<ElementType["Output"]>, never> & SetFromParentOperations<ElementType["Output"], ElementType["Error"], Parent> : TypeOperationFn<"from", ReadonlySet<ElementType["Output"]>, ReadonlySet<ElementType["Output"]>, never>;
4857
- interface SetFromParentOperations<Output, Error extends TypeError, Boundary extends TypeNode> {
4858
- readonly parent: TypeOperationFn<"from", ReadonlySet<Boundary["Output"]>, ReadonlySet<Output>, SetElementsError<Error>> & ([Boundary["parent"]] extends [infer Parent extends TypeNode] ? SetFromParentOperations<Output, Error | Boundary["Error"], Parent> : unknown);
4859
- }
4860
- type SetParent<ElementType extends TypeNode> = [ElementType["parent"]] extends [
4861
- infer ParentElement extends TypeNode
4862
- ] ? SetType<ParentElement> : null;
4863
- type SetNodeError<ElementType extends TypeNode> = [
4864
- ElementType["parent"]
4865
- ] extends [TypeNode] ? SetElementsError<ElementType["Error"]> : SetError<ElementType["Error"]>;
4866
4891
  /**
4867
4892
  * Error returned by {@link set} for a non-Set value or invalid Set items.
4868
4893
  *
@@ -4889,7 +4914,6 @@ export interface SetExcessPropertyIssue {
4889
4914
  readonly kind: "ExcessProperty";
4890
4915
  readonly key: string | symbol;
4891
4916
  }
4892
- type SetStructuralIssue = SetExcessPropertyIssue;
4893
4917
  /**
4894
4918
  * An invalid Set element and its iteration index.
4895
4919
  *
@@ -4907,43 +4931,71 @@ export type SetElementIssue<Error extends TypeError> = Error extends TypeError ?
4907
4931
  */
4908
4932
  export type SetItemsError<Error extends TypeError> = SetItemsErrorValue<Error, true>;
4909
4933
  /**
4910
- * A {@link set} error containing element errors from a typed boundary.
4934
+ * The shape of {@link SetItemsError} and {@link SetElementsError}.
4935
+ *
4936
+ * Structural issues are included only when `IncludeStructuralIssues` is true
4937
+ * because a typed boundary asserts the Set structure.
4911
4938
  *
4912
4939
  * @group Collection
4913
4940
  */
4914
- export type SetElementsError<Error extends TypeError> = [Error] extends [never] ? never : SetItemsErrorValue<Error, false>;
4915
- interface SetItemsErrorValue<Error extends TypeError, IncludeStructuralIssues extends boolean> extends TypeError<"Set"> {
4941
+ export interface SetItemsErrorValue<Error extends TypeError, IncludeStructuralIssues extends boolean> extends TypeError<"Set"> {
4916
4942
  readonly reason: {
4917
4943
  readonly kind: "Items";
4918
4944
  readonly issues: NonEmptyReadonlyArray<(true extends IncludeStructuralIssues ? SetStructuralIssue : never) | SetElementIssue<Error>>;
4919
4945
  };
4920
4946
  }
4921
4947
  /**
4922
- * Map {@link Type} whose keys and values must match their respective Types.
4948
+ * A {@link set} error containing element errors from a typed boundary.
4923
4949
  *
4924
- * Maps from this or another realm are accepted. A Map must have no own
4925
- * properties; its entries are validated in iteration order. When distinct input
4926
- * keys decode to the same output key, validation fails instead of discarding
4927
- * one associated value. Classification uses the realm-neutral object tag under
4928
- * Evolu Type's trusted JavaScript policy.
4950
+ * @group Collection
4951
+ */
4952
+ export type SetElementsError<Error extends TypeError> = [Error] extends [never] ? never : SetItemsErrorValue<Error, false>;
4953
+ /**
4954
+ * Set {@link Type} whose every element must match one Type.
4955
+ *
4956
+ * Sets from this or another realm are accepted. A Set must have no own
4957
+ * properties; its elements are validated in iteration order. Classification
4958
+ * uses the realm-neutral object tag under Evolu Type's trusted JavaScript
4959
+ * policy.
4929
4960
  *
4930
4961
  * ### Example
4931
4962
  *
4932
4963
  * ```ts
4933
- * import { assertOk, PositiveInt, String, map } from "@evolu/common";
4964
+ * import { assertOk, String, set } from "@evolu/common";
4934
4965
  *
4935
- * const Scores = map(String, PositiveInt);
4936
- * const scores = new Map([
4937
- * ["Ada", 10],
4938
- * ["Grace", 20],
4939
- * ]);
4966
+ * const Tags = set(String);
4967
+ * const tags = new Set(["local-first", "offline"]);
4940
4968
  *
4941
- * assertOk(Scores.fromUnknown(scores), scores);
4969
+ * assertOk(Tags.fromUnknown(tags), tags);
4942
4970
  * ```
4943
4971
  *
4944
4972
  * @group Collection
4945
4973
  */
4946
- export declare const map: <KeyType extends ConcreteTypeNode, ValueType extends ConcreteTypeNode>(key: ValidateMapKeyType<KeyType>, value: ValidateMapValueType<ValueType>) => MapType<KeyType, ValueType>;
4974
+ export declare const set: <ElementType extends ConcreteTypeNode>(element: ValidateElement<ElementType>) => SetType<ElementType>;
4975
+ type SetCustomFrom<ElementType extends TypeNode> = [
4976
+ ElementType["parent"]
4977
+ ] extends [TypeNode] ? SetFromOperation<ElementType> : never;
4978
+ type SetFromOperation<ElementType extends TypeNode> = [
4979
+ ElementType["parent"]
4980
+ ] extends [infer Parent extends TypeNode] ? TypeOperationFn<"from", ReadonlySet<ElementType["Output"]>, ReadonlySet<ElementType["Output"]>, never> & SetFromParentOperations<ElementType["Output"], ElementType["Error"], Parent> : TypeOperationFn<"from", ReadonlySet<ElementType["Output"]>, ReadonlySet<ElementType["Output"]>, never>;
4981
+ /**
4982
+ * The `.parent` suffixes of a {@link SetType} `from` operation.
4983
+ *
4984
+ * Each `.parent` accepts a Set of the next element Output toward the root and
4985
+ * returns the element errors of every boundary it adds.
4986
+ *
4987
+ * @group Collection
4988
+ */
4989
+ export interface SetFromParentOperations<Output, Error extends TypeError, Boundary extends TypeNode> {
4990
+ readonly parent: TypeOperationFn<"from", ReadonlySet<Boundary["Output"]>, ReadonlySet<Output>, SetElementsError<Error>> & ([Boundary["parent"]] extends [infer Parent extends TypeNode] ? SetFromParentOperations<Output, Error | Boundary["Error"], Parent> : unknown);
4991
+ }
4992
+ type SetParent<ElementType extends TypeNode> = [ElementType["parent"]] extends [
4993
+ infer ParentElement extends TypeNode
4994
+ ] ? SetType<ParentElement> : null;
4995
+ type SetNodeError<ElementType extends TypeNode> = [
4996
+ ElementType["parent"]
4997
+ ] extends [TypeNode] ? SetElementsError<ElementType["Error"]> : SetError<ElementType["Error"]>;
4998
+ type SetStructuralIssue = SetExcessPropertyIssue;
4947
4999
  /**
4948
5000
  * The readonly-map {@link Type} returned by {@link map}.
4949
5001
  *
@@ -4954,17 +5006,19 @@ export interface MapType<KeyType extends TypeNode, ValueType extends TypeNode> e
4954
5006
  readonly key: KeyType;
4955
5007
  readonly value: ValueType;
4956
5008
  }
4957
- type MapParent<KeyType extends TypeNode, ValueType extends TypeNode> = [
4958
- KeyType["parent"] | ValueType["parent"]
4959
- ] extends [null] ? null : MapType<RootType<KeyType>, RootType<ValueType>>;
4960
- type MapNodeError<KeyType extends TypeNode, ValueType extends TypeNode> = [
4961
- KeyType["parent"] | ValueType["parent"]
4962
- ] extends [null] ? MapError<InferErrors<KeyType>, InferErrors<ValueType>, never> : MapEntriesError<TypeFromError<KeyType>, TypeFromError<ValueType>, MapCollisionFor<KeyType>>;
4963
- type MapCollisionFor<KeyType extends TypeNode> = [KeyType["parent"]] extends [
4964
- TypeNode
4965
- ] ? MapKeyCollisionIssue : never;
4966
- type ValidateMapKeyType<T extends ConcreteTypeNode> = IsUnion<T> extends false ? T : CompileTimeError<"Type", "Map key must use one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
4967
- type ValidateMapValueType<T extends ConcreteTypeNode> = IsUnion<T> extends false ? T : CompileTimeError<"Type", "Map value must use one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
5009
+ /**
5010
+ * The parent of a {@link MapType} whose key or value Type has a parent.
5011
+ *
5012
+ * Its key and value are the root Types of the child map's key and value, and it
5013
+ * has no parent itself.
5014
+ *
5015
+ * @group Collection
5016
+ */
5017
+ export interface RootMapType<KeyType extends TypeNode, ValueType extends TypeNode> extends Type<"Map", ReadonlyMap<KeyType["Input"], ValueType["Input"]>, ReadonlyMap<KeyType["Output"], ValueType["Output"]>, MapError<InferErrors<KeyType>, InferErrors<ValueType>, never>, null, MapError<InferErrors<KeyType>, InferErrors<ValueType>, never>, never, CanonicalInputSubset<ReadonlyMap<KeyType["Input"], ValueType["Input"]>, ReadonlyMap<CanonicalInputOf<KeyType>, CanonicalInputOf<ValueType>>>, AllTypesUseIdentityEncoding<KeyType | ValueType>> {
5018
+ readonly [reflectedTypesSymbol]?: KeyType | ValueType;
5019
+ readonly key: KeyType;
5020
+ readonly value: ValueType;
5021
+ }
4968
5022
  /**
4969
5023
  * Error returned while validating a {@link map} and its entries.
4970
5024
  *
@@ -5026,7 +5080,6 @@ export interface MapKeyCollisionIssue {
5026
5080
  readonly previousKey: unknown;
5027
5081
  readonly outputKey: unknown;
5028
5082
  }
5029
- type MapStructuralIssue = MapExcessPropertyIssue | MapKeyCollisionIssue;
5030
5083
  /**
5031
5084
  * An invalid key, value, or structure in a {@link map}.
5032
5085
  *
@@ -5039,52 +5092,55 @@ export type MapIssue<KeyError extends TypeError, ValueError extends TypeError, S
5039
5092
  * @group Collection
5040
5093
  */
5041
5094
  export type MapEntriesError<KeyError extends TypeError, ValueError extends TypeError, StructuralIssue extends MapStructuralIssue = MapKeyCollisionIssue> = [KeyError | ValueError | StructuralIssue] extends [never] ? never : MapEntriesErrorValue<KeyError, ValueError, StructuralIssue>;
5042
- interface MapEntriesErrorValue<KeyError extends TypeError, ValueError extends TypeError, StructuralIssue extends MapStructuralIssue> extends TypeError<"Map"> {
5043
- readonly reason: {
5044
- readonly kind: "Entries";
5095
+ /**
5096
+ * The entry error shape of {@link MapError} and {@link MapEntriesError}.
5097
+ *
5098
+ * @group Collection
5099
+ */
5100
+ export interface MapEntriesErrorValue<KeyError extends TypeError, ValueError extends TypeError, StructuralIssue extends MapStructuralIssue> extends TypeError<"Map"> {
5101
+ readonly reason: {
5102
+ readonly kind: "Entries";
5045
5103
  readonly issues: NonEmptyReadonlyArray<MapKeyIssue<KeyError> | MapValueIssue<ValueError> | StructuralIssue>;
5046
5104
  };
5047
5105
  }
5048
5106
  /**
5049
- * Tuple {@link Type}.
5050
- *
5051
- * Use `tuple(First, Second, ...)` for a fixed-length readonly array in which
5052
- * every position has its own Type.
5053
- *
5054
- * `fromUnknown` validates the Tuple representation and runs every element's
5055
- * complete Type pipeline. By default, it returns the first issue. Pass `{
5056
- * errors: "all" }` to collect issues across the whole Tuple.
5057
- *
5058
- * `from` accepts the Tuple Output. When any element Type has a parent,
5059
- * `from.parent` accepts a Tuple of root element Outputs and runs all remaining
5060
- * element stages. This collapsed input boundary keeps a Tuple to at most one
5061
- * `.parent` suffix even when its element Types have different pipeline depths.
5107
+ * Map {@link Type} whose keys and values must match their respective Types.
5062
5108
  *
5063
- * A Tuple must be recognized by `Array.isArray`, have exactly the declared
5064
- * length, be dense, and have no own properties other than `length` and the
5065
- * indexed data properties for its elements. Foreign-realm arrays are accepted
5066
- * when their own data representation is valid. Sparse arrays, accessor
5067
- * elements, and excess properties are rejected.
5109
+ * Maps from this or another realm are accepted. A Map must have no own
5110
+ * properties; its entries are validated in iteration order. When distinct input
5111
+ * keys decode to the same output key, validation fails instead of discarding
5112
+ * one associated value. Classification uses the realm-neutral object tag under
5113
+ * Evolu Type's trusted JavaScript policy.
5068
5114
  *
5069
5115
  * ### Example
5070
5116
  *
5071
5117
  * ```ts
5072
- * import {
5073
- * assertOk,
5074
- * Int64FromInt64String,
5075
- * String,
5076
- * tuple,
5077
- * } from "@evolu/common";
5118
+ * import { assertOk, PositiveInt, String, map } from "@evolu/common";
5078
5119
  *
5079
- * const Entry = tuple(String, Int64FromInt64String);
5120
+ * const Scores = map(String, PositiveInt);
5121
+ * const scores = new Map([
5122
+ * ["Ada", 10],
5123
+ * ["Grace", 20],
5124
+ * ]);
5080
5125
  *
5081
- * assertOk(Entry.fromUnknown(["count", "1"]), ["count", 1n]);
5082
- * assertOk(Entry.from.parent(["count", "1"]), ["count", 1n]);
5126
+ * assertOk(Scores.fromUnknown(scores), scores);
5083
5127
  * ```
5084
5128
  *
5085
5129
  * @group Collection
5086
5130
  */
5087
- export declare function tuple<const Elements extends TupleElements>(...elements: Elements & TupleValidation<Elements>): TupleType<Elements>;
5131
+ export declare const map: <KeyType extends ConcreteTypeNode, ValueType extends ConcreteTypeNode>(key: ValidateMapKeyType<KeyType>, value: ValidateMapValueType<ValueType>) => MapType<KeyType, ValueType>;
5132
+ type MapParent<KeyType extends TypeNode, ValueType extends TypeNode> = [
5133
+ KeyType["parent"] | ValueType["parent"]
5134
+ ] extends [null] ? null : RootMapType<RootType<KeyType>, RootType<ValueType>>;
5135
+ type MapNodeError<KeyType extends TypeNode, ValueType extends TypeNode> = [
5136
+ KeyType["parent"] | ValueType["parent"]
5137
+ ] extends [null] ? MapError<InferErrors<KeyType>, InferErrors<ValueType>, never> : MapEntriesError<TypeFromError<KeyType>, TypeFromError<ValueType>, MapCollisionFor<KeyType>>;
5138
+ type MapCollisionFor<KeyType extends TypeNode> = [KeyType["parent"]] extends [
5139
+ TypeNode
5140
+ ] ? MapKeyCollisionIssue : never;
5141
+ type ValidateMapKeyType<T extends ConcreteTypeNode> = IsUnion<T> extends false ? T : CompileTimeError<"Type", "Map key must use one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
5142
+ type ValidateMapValueType<T extends ConcreteTypeNode> = IsUnion<T> extends false ? T : CompileTimeError<"Type", "Map value must use one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
5143
+ type MapStructuralIssue = MapExcessPropertyIssue | MapKeyCollisionIssue;
5088
5144
  /**
5089
5145
  * The fixed-length heterogeneous {@link Type} returned by {@link tuple}.
5090
5146
  *
@@ -5098,29 +5154,18 @@ export interface TupleType<Elements extends TupleElements> extends Type<"Tuple",
5098
5154
  readonly [reflectedTypesSymbol]?: Elements[number];
5099
5155
  readonly elements: Elements;
5100
5156
  }
5101
- type TupleElements = NonEmptyReadonlyArray<TypeNode>;
5102
- type TupleShape<Elements extends TupleElements, Field extends "Input" | "Output" | "CanonicalInput"> = {
5103
- readonly [Index in keyof Elements]: Elements[Index] extends TypeNode ? Field extends "CanonicalInput" ? CanonicalInputOf<Elements[Index]> : Elements[Index][Field] : never;
5104
- };
5105
- type TupleParents<Elements extends TupleElements> = Elements[number]["parent"];
5106
- type TupleFromErrors<Elements extends TupleElements> = {
5107
- readonly [Index in keyof Elements]: Elements[Index] extends TypeNode ? TypeFromError<Elements[Index]> : never;
5108
- }[number];
5109
- type RootTupleElements<Elements extends TupleElements> = {
5110
- readonly [Index in keyof Elements]: Elements[Index] extends TypeNode ? RootType<Elements[Index]> : never;
5111
- };
5112
- type RootTupleType<Elements extends TupleElements> = Type<"Tuple", TupleShape<Elements, "Input">, TupleShape<Elements, "Output">, TupleError<Elements[number]["Error"]>, null, TupleError<Elements[number]["Error"]>, never, TupleShape<Elements, "CanonicalInput">, AllTypesUseIdentityEncoding<Elements[number]>> & {
5157
+ /**
5158
+ * The parent of a {@link TupleType} whose elements have parents.
5159
+ *
5160
+ * Its elements are the root Types of the child tuple's elements, and it has no
5161
+ * parent itself.
5162
+ *
5163
+ * @group Collection
5164
+ */
5165
+ export interface RootTupleType<Elements extends TupleElements> extends Type<"Tuple", TupleShape<Elements, "Input">, TupleShape<Elements, "Output">, TupleError<Elements[number]["Error"]>, null, TupleError<Elements[number]["Error"]>, never, TupleShape<Elements, "CanonicalInput">, AllTypesUseIdentityEncoding<Elements[number]>> {
5113
5166
  readonly [reflectedTypesSymbol]?: Elements[number];
5114
5167
  readonly elements: Elements;
5115
- };
5116
- type TupleValidation<Elements extends TupleElements> = [
5117
- ValidateTupleElements<Elements>
5118
- ] extends [never] ? unknown : readonly [ValidationFailure<ValidateTupleElements<Elements>>];
5119
- type ValidateTupleElements<Elements extends TupleElements> = number extends Elements["length"] ? TupleElementsTupleError : IsUnion<Elements["length"]> extends false ? {
5120
- readonly [Index in keyof Elements & `${number}`]: IsUnion<Elements[Index]> extends false ? Elements[Index] extends ConcreteTypeNode ? never : TupleElementConcreteTypeError : TupleElementConcreteTypeError;
5121
- }[keyof Elements & `${number}`] : TupleElementsTupleError;
5122
- type TupleElementsTupleError = CompileTimeError<"Type", "Elements must use one concrete finite non-empty tuple of Types.">;
5123
- type TupleElementConcreteTypeError = CompileTimeError<"Type", "Element must use one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
5168
+ }
5124
5169
  /**
5125
5170
  * An error returned while validating a {@link tuple}.
5126
5171
  *
@@ -5156,6 +5201,20 @@ export interface TupleInvalidLengthError extends TypeError<"Tuple"> {
5156
5201
  * @group Collection
5157
5202
  */
5158
5203
  export type TupleItemsError<Error extends TypeError> = TupleItemsErrorValue<Error, true>;
5204
+ /**
5205
+ * The shape of {@link TupleItemsError} and {@link TupleElementsError}.
5206
+ *
5207
+ * Structural issues are included only when `IncludeStructuralIssues` is true
5208
+ * because a typed boundary asserts the tuple structure.
5209
+ *
5210
+ * @group Collection
5211
+ */
5212
+ export interface TupleItemsErrorValue<Error extends TypeError, IncludeStructuralIssues extends boolean> extends TypeError<"Tuple"> {
5213
+ readonly reason: {
5214
+ readonly kind: "Items";
5215
+ readonly issues: NonEmptyReadonlyArray<(true extends IncludeStructuralIssues ? TupleStructuralIssue : never) | TupleElementIssue<Error>>;
5216
+ };
5217
+ }
5159
5218
  /**
5160
5219
  * One structural or element issue found in a {@link tuple}.
5161
5220
  *
@@ -5189,7 +5248,6 @@ export interface TupleExcessPropertyIssue {
5189
5248
  readonly kind: "ExcessProperty";
5190
5249
  readonly key: string | symbol;
5191
5250
  }
5192
- type TupleStructuralIssue = TupleHoleIssue | TupleAccessorIssue | TupleExcessPropertyIssue;
5193
5251
  /**
5194
5252
  * An error returned by one element Type in a {@link tuple}.
5195
5253
  *
@@ -5208,12 +5266,66 @@ export type TupleElementIssue<Error extends TypeError> = Error extends TypeError
5208
5266
  export type TupleElementsError<Error extends TypeError> = [Error] extends [
5209
5267
  never
5210
5268
  ] ? never : TupleItemsErrorValue<Error, false>;
5211
- interface TupleItemsErrorValue<Error extends TypeError, IncludeStructuralIssues extends boolean> extends TypeError<"Tuple"> {
5212
- readonly reason: {
5213
- readonly kind: "Items";
5214
- readonly issues: NonEmptyReadonlyArray<(true extends IncludeStructuralIssues ? TupleStructuralIssue : never) | TupleElementIssue<Error>>;
5215
- };
5216
- }
5269
+ /**
5270
+ * Tuple {@link Type}.
5271
+ *
5272
+ * Use `tuple(First, Second, ...)` for a fixed-length readonly array in which
5273
+ * every position has its own Type.
5274
+ *
5275
+ * `fromUnknown` validates the Tuple representation and runs every element's
5276
+ * complete Type pipeline. By default, it returns the first issue. Pass `{
5277
+ * errors: "all" }` to collect issues across the whole Tuple.
5278
+ *
5279
+ * `from` accepts the Tuple Output. When any element Type has a parent,
5280
+ * `from.parent` accepts a Tuple of root element Outputs and runs all remaining
5281
+ * element stages. This collapsed input boundary keeps a Tuple to at most one
5282
+ * `.parent` suffix even when its element Types have different pipeline depths.
5283
+ *
5284
+ * A Tuple must be recognized by `Array.isArray`, have exactly the declared
5285
+ * length, be dense, and have no own properties other than `length` and the
5286
+ * indexed data properties for its elements. Foreign-realm arrays are accepted
5287
+ * when their own data representation is valid. Sparse arrays, accessor
5288
+ * elements, and excess properties are rejected.
5289
+ *
5290
+ * ### Example
5291
+ *
5292
+ * ```ts
5293
+ * import {
5294
+ * assertOk,
5295
+ * Int64FromInt64String,
5296
+ * String,
5297
+ * tuple,
5298
+ * } from "@evolu/common";
5299
+ *
5300
+ * const Entry = tuple(String, Int64FromInt64String);
5301
+ *
5302
+ * assertOk(Entry.fromUnknown(["count", "1"]), ["count", 1n]);
5303
+ * assertOk(Entry.from.parent(["count", "1"]), ["count", 1n]);
5304
+ * ```
5305
+ *
5306
+ * @group Collection
5307
+ */
5308
+ export declare function tuple<const Elements extends TupleElements>(...elements: Elements & TupleValidation<Elements>): TupleType<Elements>;
5309
+ type TupleElements = NonEmptyReadonlyArray<TypeNode>;
5310
+ type TupleShape<Elements extends TupleElements, Field extends "Input" | "Output" | "CanonicalInput"> = {
5311
+ readonly [Index in keyof Elements]: Elements[Index] extends TypeNode ? Field extends "CanonicalInput" ? CanonicalInputOf<Elements[Index]> : Elements[Index][Field] : never;
5312
+ };
5313
+ type TupleParents<Elements extends TupleElements> = Elements[number]["parent"];
5314
+ type TupleFromErrors<Elements extends TupleElements> = {
5315
+ readonly [Index in keyof Elements]: Elements[Index] extends TypeNode ? TypeFromError<Elements[Index]> : never;
5316
+ }[number];
5317
+ type RootTupleElements<Elements extends TupleElements> = {
5318
+ readonly [Index in keyof Elements]: Elements[Index] extends TypeNode ? RootType<Elements[Index]> : never;
5319
+ };
5320
+ type TupleValidation<Elements extends TupleElements> = [
5321
+ ValidateTupleElements<Elements>
5322
+ ] extends [never] ? unknown : readonly [ValidationFailure<ValidateTupleElements<Elements>>];
5323
+ type ValidateTupleElements<Elements extends TupleElements> = number extends Elements["length"] ? TupleElementsTupleError : IsUnion<Elements["length"]> extends false ? {
5324
+ readonly [Index in keyof Elements & `${number}`]: IsUnion<Elements[Index]> extends false ? Elements[Index] extends ConcreteTypeNode ? never : TupleElementConcreteTypeError : TupleElementConcreteTypeError;
5325
+ }[keyof Elements & `${number}`] : TupleElementsTupleError;
5326
+ type TupleElementsTupleError = CompileTimeError<"Type", "Elements must use one concrete finite non-empty tuple of Types.">;
5327
+ type TupleElementConcreteTypeError = CompileTimeError<"Type", "Element must use one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
5328
+ type TupleStructuralIssue = TupleHoleIssue | TupleAccessorIssue | TupleExcessPropertyIssue;
5217
5329
  /**
5218
5330
  * Decimal integer string from `"0"` to `"9"`.
5219
5331
  *
@@ -5323,52 +5435,185 @@ type PlainObjectError = ObjectError<Readonly<Record<never, never>>, ObjectProper
5323
5435
  declare const _Object: Type<"Object", Readonly<Record<string, unknown>>, Readonly<Record<string, unknown>>, PlainObjectError, null, PlainObjectError, never, Readonly<Record<string, unknown>>>;
5324
5436
  export { _Object as Object };
5325
5437
  /**
5326
- * Record {@link Type}.
5438
+ * The {@link Type} returned by {@link record}.
5327
5439
  *
5328
- * Use `record(Key, Value)` for readonly Records with dynamic string keys, such
5329
- * as scores by user ID or settings by name. Use {@link object} when property
5330
- * names are fixed.
5440
+ * @group Objects
5441
+ */
5442
+ export interface RecordType<KeyType extends TypeNode, ValueType extends TypeNode> extends Type<"Record", RecordShape<KeyType, ValueType, "Input">, RecordShape<KeyType, ValueType, "Output">, RecordNodeError<KeyType, ValueType>, RecordParent<KeyType, ValueType>, RecordError<InferErrors<KeyType>, InferErrors<ValueType>, RecordCollisionFor<KeyType>>, never, CanonicalInputSubset<RecordShape<KeyType, ValueType, "Input">, RecordShape<KeyType, ValueType, "CanonicalInput">>, AllTypesUseIdentityEncoding<KeyType | ValueType>> {
5443
+ readonly [reflectedTypesSymbol]?: KeyType | ValueType;
5444
+ readonly key: KeyType;
5445
+ readonly value: ValueType;
5446
+ }
5447
+ /**
5448
+ * The parent of a {@link RecordType} whose key or value Type has a parent.
5331
5449
  *
5332
- * `fromUnknown` validates the Record and runs the complete `Key` and `Value`
5333
- * pipelines. `from` accepts the Record Output. When either entry Type has a
5334
- * parent, `from.parent` accepts a Record of their root Outputs and runs their
5335
- * remaining stages. This collapsed input boundary keeps a Record to at most one
5336
- * `.parent` suffix.
5450
+ * Its key and value are the root Types of the child record's key and value, and
5451
+ * it has no parent itself.
5337
5452
  *
5338
- * By default, validation returns the first issue. Pass `{ errors: "all" }` to
5339
- * collect issues across the whole Record.
5453
+ * @group Objects
5454
+ */
5455
+ export interface RootRecordType<KeyType extends TypeNode, ValueType extends TypeNode> extends Type<"Record", RecordShape<KeyType, ValueType, "Input">, RecordShape<KeyType, ValueType, "Output">, RecordError<InferErrors<KeyType>, InferErrors<ValueType>, never>, null, RecordError<InferErrors<KeyType>, InferErrors<ValueType>, never>, never, CanonicalInputSubset<RecordShape<KeyType, ValueType, "Input">, RecordShape<KeyType, ValueType, "CanonicalInput">>, AllTypesUseIdentityEncoding<KeyType | ValueType>> {
5456
+ readonly [reflectedTypesSymbol]?: KeyType | ValueType;
5457
+ readonly key: KeyType;
5458
+ readonly value: ValueType;
5459
+ }
5460
+ /**
5461
+ * Error returned while validating a {@link record} and its entries.
5340
5462
  *
5341
- * A Record must satisfy the realm-neutral structural heuristic described by
5342
- * {@link isPlainObject}. A matching custom root prototype can be classified as
5343
- * plain; other custom prototypes and class instances are rejected. Every own
5344
- * property must be an enumerable data property whose key and value satisfy
5345
- * their Types. When decoding or encoding changes an entry, the constructed
5346
- * Record uses a `null` prototype so keys such as `__proto__` remain ordinary
5347
- * data.
5463
+ * @group Objects
5464
+ */
5465
+ export type RecordError<KeyError extends TypeError = TypeError, ValueError extends TypeError = TypeError, Collision extends RecordCollisionIssue = RecordCollisionIssue> = RecordNotRecordError | RecordNotPlainRecordError | RecordEntriesErrorValue<KeyError, ValueError, Collision | RecordAccessorIssue | RecordNonEnumerableIssue>;
5466
+ /**
5467
+ * Error returned when a {@link record} input is not an object.
5348
5468
  *
5349
- * If transformed keys collide, validation fails instead of overwriting an
5350
- * entry.
5469
+ * @group Objects
5470
+ */
5471
+ export interface RecordNotRecordError extends TypeError<"Record"> {
5472
+ readonly reason: {
5473
+ readonly kind: "NotRecord";
5474
+ readonly value: unknown;
5475
+ };
5476
+ }
5477
+ /**
5478
+ * Error returned when a {@link record} input is not a plain object.
5351
5479
  *
5352
- * ### Example
5480
+ * @group Objects
5481
+ */
5482
+ export interface RecordNotPlainRecordError extends TypeError<"Record"> {
5483
+ readonly reason: {
5484
+ readonly kind: "NotPlainRecord";
5485
+ readonly value: object;
5486
+ };
5487
+ }
5488
+ /**
5489
+ * Entry errors returned by a {@link record} operation.
5353
5490
  *
5354
- * ```ts
5355
- * import {
5356
- * assertOk,
5357
- * assertType,
5358
- * Int64FromInt64String,
5359
- * String,
5360
- * record,
5361
- * type Int64,
5362
- * } from "@evolu/common";
5491
+ * Property structure is omitted by default because typed operations assert
5492
+ * enumerable own data properties. {@link RecordError} includes structural issues
5493
+ * at the unknown-input boundary.
5363
5494
  *
5364
- * const ScoresByUser = record(String, Int64FromInt64String);
5365
- * type ScoresByUser = typeof ScoresByUser.Output;
5495
+ * @group Objects
5496
+ */
5497
+ export type RecordEntriesError<KeyError extends TypeError, ValueError extends TypeError, StructuralIssue extends RecordStructuralIssue = RecordCollisionIssue> = [KeyError | ValueError | StructuralIssue] extends [never] ? never : RecordEntriesErrorValue<KeyError, ValueError, StructuralIssue>;
5498
+ /**
5499
+ * The entry error shape of {@link RecordError} and {@link RecordEntriesError}.
5366
5500
  *
5367
- * // Validate an unknown value.
5368
- * const scoresFromUnknown = ScoresByUser.fromUnknown({
5369
- * ada: "10",
5370
- * grace: "20",
5371
- * });
5501
+ * @group Objects
5502
+ */
5503
+ export interface RecordEntriesErrorValue<KeyError extends TypeError, ValueError extends TypeError, StructuralIssue extends RecordStructuralIssue> extends TypeError<"Record"> {
5504
+ readonly reason: {
5505
+ readonly kind: "Entries";
5506
+ readonly issues: NonEmptyReadonlyArray<RecordKeyIssue<KeyError> | RecordValueIssue<ValueError> | StructuralIssue>;
5507
+ };
5508
+ }
5509
+ /**
5510
+ * An invalid key, value, or property structure in a {@link record}.
5511
+ *
5512
+ * @group Objects
5513
+ */
5514
+ export type RecordIssue<KeyError extends TypeError, ValueError extends TypeError, StructuralIssue extends RecordStructuralIssue = RecordCollisionIssue> = RecordKeyIssue<KeyError> | RecordValueIssue<ValueError> | StructuralIssue;
5515
+ /**
5516
+ * A property-structure issue returned by {@link record}.
5517
+ *
5518
+ * @group Objects
5519
+ */
5520
+ export type RecordStructuralIssue = RecordAccessorIssue | RecordCollisionIssue | RecordNonEnumerableIssue;
5521
+ /**
5522
+ * An accessor property rejected by {@link record}.
5523
+ *
5524
+ * @group Objects
5525
+ */
5526
+ export interface RecordAccessorIssue {
5527
+ readonly kind: "Accessor";
5528
+ readonly key: string | symbol;
5529
+ }
5530
+ /**
5531
+ * A non-enumerable property rejected by {@link record}.
5532
+ *
5533
+ * @group Objects
5534
+ */
5535
+ export interface RecordNonEnumerableIssue {
5536
+ readonly kind: "NonEnumerable";
5537
+ readonly key: string | symbol;
5538
+ }
5539
+ /**
5540
+ * An invalid key and its source property key in a {@link record}.
5541
+ *
5542
+ * @group Objects
5543
+ */
5544
+ export type RecordKeyIssue<Error extends TypeError> = Error extends TypeError ? {
5545
+ readonly kind: "Key";
5546
+ readonly key: string | symbol;
5547
+ readonly error: Error;
5548
+ } : never;
5549
+ /**
5550
+ * An invalid value and its property key in a {@link record}.
5551
+ *
5552
+ * @group Objects
5553
+ */
5554
+ export type RecordValueIssue<Error extends TypeError> = Error extends TypeError ? {
5555
+ readonly kind: "Value";
5556
+ readonly key: string | symbol;
5557
+ readonly error: Error;
5558
+ } : never;
5559
+ /**
5560
+ * Two {@link record} keys that decode to the same output key.
5561
+ *
5562
+ * @group Objects
5563
+ */
5564
+ export interface RecordCollisionIssue {
5565
+ readonly kind: "Collision";
5566
+ readonly key: string | symbol;
5567
+ readonly previousKey: string | symbol;
5568
+ readonly outputKey: string;
5569
+ }
5570
+ /**
5571
+ * Record {@link Type}.
5572
+ *
5573
+ * Use `record(Key, Value)` for readonly Records with dynamic string keys, such
5574
+ * as scores by user ID or settings by name. Use {@link object} when property
5575
+ * names are fixed.
5576
+ *
5577
+ * `fromUnknown` validates the Record and runs the complete `Key` and `Value`
5578
+ * pipelines. `from` accepts the Record Output. When either entry Type has a
5579
+ * parent, `from.parent` accepts a Record of their root Outputs and runs their
5580
+ * remaining stages. This collapsed input boundary keeps a Record to at most one
5581
+ * `.parent` suffix.
5582
+ *
5583
+ * By default, validation returns the first issue. Pass `{ errors: "all" }` to
5584
+ * collect issues across the whole Record.
5585
+ *
5586
+ * A Record must satisfy the realm-neutral structural heuristic described by
5587
+ * {@link isPlainObject}. A matching custom root prototype can be classified as
5588
+ * plain; other custom prototypes and class instances are rejected. Every own
5589
+ * property must be an enumerable data property whose key and value satisfy
5590
+ * their Types. When decoding or encoding changes an entry, the constructed
5591
+ * Record uses a `null` prototype so keys such as `__proto__` remain ordinary
5592
+ * data.
5593
+ *
5594
+ * If transformed keys collide, validation fails instead of overwriting an
5595
+ * entry.
5596
+ *
5597
+ * ### Example
5598
+ *
5599
+ * ```ts
5600
+ * import {
5601
+ * assertOk,
5602
+ * assertType,
5603
+ * Int64FromInt64String,
5604
+ * String,
5605
+ * record,
5606
+ * type Int64,
5607
+ * } from "@evolu/common";
5608
+ *
5609
+ * const ScoresByUser = record(String, Int64FromInt64String);
5610
+ * type ScoresByUser = typeof ScoresByUser.Output;
5611
+ *
5612
+ * // Validate an unknown value.
5613
+ * const scoresFromUnknown = ScoresByUser.fromUnknown({
5614
+ * ada: "10",
5615
+ * grace: "20",
5616
+ * });
5372
5617
  *
5373
5618
  * assertOk(scoresFromUnknown, { ada: 10n, grace: 20n });
5374
5619
  *
@@ -5462,16 +5707,6 @@ export { _Object as Object };
5462
5707
  * @group Objects
5463
5708
  */
5464
5709
  export declare const record: <KeyType extends ConcreteTypeNode, ValueType extends ConcreteTypeNode>(key: ValidateRecordKeyType<KeyType>, value: ValidateRecordValueType<ValueType>) => RecordType<KeyType, ValueType>;
5465
- /**
5466
- * The {@link Type} returned by {@link record}.
5467
- *
5468
- * @group Objects
5469
- */
5470
- export interface RecordType<KeyType extends TypeNode, ValueType extends TypeNode> extends Type<"Record", RecordShape<KeyType, ValueType, "Input">, RecordShape<KeyType, ValueType, "Output">, RecordNodeError<KeyType, ValueType>, RecordParent<KeyType, ValueType>, RecordError<InferErrors<KeyType>, InferErrors<ValueType>, RecordCollisionFor<KeyType>>, never, CanonicalInputSubset<RecordShape<KeyType, ValueType, "Input">, RecordShape<KeyType, ValueType, "CanonicalInput">>, AllTypesUseIdentityEncoding<KeyType | ValueType>> {
5471
- readonly [reflectedTypesSymbol]?: KeyType | ValueType;
5472
- readonly key: KeyType;
5473
- readonly value: ValueType;
5474
- }
5475
5710
  interface RecordTypeNode extends TypeNode {
5476
5711
  readonly name: "Record";
5477
5712
  readonly key: TypeNode;
@@ -5494,7 +5729,7 @@ type RecordShape<KeyType extends TypeNode, ValueType extends TypeNode, Field ext
5494
5729
  type RecordTypeField<T extends TypeNode, Field extends "Input" | "Output" | "CanonicalInput"> = Field extends "CanonicalInput" ? CanonicalInputOf<T> : T[Field];
5495
5730
  type RecordParent<KeyType extends TypeNode, ValueType extends TypeNode> = [
5496
5731
  KeyType["parent"] | ValueType["parent"]
5497
- ] extends [null] ? null : RecordType<RootType<KeyType>, RootType<ValueType>>;
5732
+ ] extends [null] ? null : RootRecordType<RootType<KeyType>, RootType<ValueType>>;
5498
5733
  type RecordNodeError<KeyType extends TypeNode, ValueType extends TypeNode> = [
5499
5734
  KeyType["parent"] | ValueType["parent"]
5500
5735
  ] extends [null] ? RecordError<InferErrors<KeyType>, InferErrors<ValueType>, never> : RecordEntriesError<TypeFromError<KeyType>, TypeFromError<ValueType>, RecordCollisionFor<KeyType>>;
@@ -5506,111 +5741,6 @@ type ValidateRecordValueType<T extends ConcreteTypeNode> = IsUnion<T> extends fa
5506
5741
  type RecordKeyConcreteTypeError = CompileTimeError<"Type", "Record key must use one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
5507
5742
  type RecordValueConcreteTypeError = CompileTimeError<"Type", "Record value must use one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
5508
5743
  type RecordKeyStringTypeError = CompileTimeError<"Type", "Record key Type Input and Output must extend string.">;
5509
- /**
5510
- * Error returned while validating a {@link record} and its entries.
5511
- *
5512
- * @group Objects
5513
- */
5514
- export type RecordError<KeyError extends TypeError = TypeError, ValueError extends TypeError = TypeError, Collision extends RecordCollisionIssue = RecordCollisionIssue> = RecordNotRecordError | RecordNotPlainRecordError | RecordEntriesErrorValue<KeyError, ValueError, Collision | RecordAccessorIssue | RecordNonEnumerableIssue>;
5515
- /**
5516
- * Error returned when a {@link record} input is not an object.
5517
- *
5518
- * @group Objects
5519
- */
5520
- export interface RecordNotRecordError extends TypeError<"Record"> {
5521
- readonly reason: {
5522
- readonly kind: "NotRecord";
5523
- readonly value: unknown;
5524
- };
5525
- }
5526
- /**
5527
- * Error returned when a {@link record} input is not a plain object.
5528
- *
5529
- * @group Objects
5530
- */
5531
- export interface RecordNotPlainRecordError extends TypeError<"Record"> {
5532
- readonly reason: {
5533
- readonly kind: "NotPlainRecord";
5534
- readonly value: object;
5535
- };
5536
- }
5537
- /**
5538
- * Entry errors returned by a {@link record} operation.
5539
- *
5540
- * Property structure is omitted by default because typed operations assert
5541
- * enumerable own data properties. {@link RecordError} includes structural issues
5542
- * at the unknown-input boundary.
5543
- *
5544
- * @group Objects
5545
- */
5546
- export type RecordEntriesError<KeyError extends TypeError, ValueError extends TypeError, StructuralIssue extends RecordStructuralIssue = RecordCollisionIssue> = [KeyError | ValueError | StructuralIssue] extends [never] ? never : RecordEntriesErrorValue<KeyError, ValueError, StructuralIssue>;
5547
- /**
5548
- * An invalid key, value, or property structure in a {@link record}.
5549
- *
5550
- * @group Objects
5551
- */
5552
- export type RecordIssue<KeyError extends TypeError, ValueError extends TypeError, StructuralIssue extends RecordStructuralIssue = RecordCollisionIssue> = RecordKeyIssue<KeyError> | RecordValueIssue<ValueError> | StructuralIssue;
5553
- /**
5554
- * A property-structure issue returned by {@link record}.
5555
- *
5556
- * @group Objects
5557
- */
5558
- export type RecordStructuralIssue = RecordAccessorIssue | RecordCollisionIssue | RecordNonEnumerableIssue;
5559
- /**
5560
- * An accessor property rejected by {@link record}.
5561
- *
5562
- * @group Objects
5563
- */
5564
- export interface RecordAccessorIssue {
5565
- readonly kind: "Accessor";
5566
- readonly key: string | symbol;
5567
- }
5568
- /**
5569
- * A non-enumerable property rejected by {@link record}.
5570
- *
5571
- * @group Objects
5572
- */
5573
- export interface RecordNonEnumerableIssue {
5574
- readonly kind: "NonEnumerable";
5575
- readonly key: string | symbol;
5576
- }
5577
- /**
5578
- * An invalid key and its source property key in a {@link record}.
5579
- *
5580
- * @group Objects
5581
- */
5582
- export type RecordKeyIssue<Error extends TypeError> = Error extends TypeError ? {
5583
- readonly kind: "Key";
5584
- readonly key: string | symbol;
5585
- readonly error: Error;
5586
- } : never;
5587
- /**
5588
- * An invalid value and its property key in a {@link record}.
5589
- *
5590
- * @group Objects
5591
- */
5592
- export type RecordValueIssue<Error extends TypeError> = Error extends TypeError ? {
5593
- readonly kind: "Value";
5594
- readonly key: string | symbol;
5595
- readonly error: Error;
5596
- } : never;
5597
- /**
5598
- * Two {@link record} keys that decode to the same output key.
5599
- *
5600
- * @group Objects
5601
- */
5602
- export interface RecordCollisionIssue {
5603
- readonly kind: "Collision";
5604
- readonly key: string | symbol;
5605
- readonly previousKey: string | symbol;
5606
- readonly outputKey: string;
5607
- }
5608
- interface RecordEntriesErrorValue<KeyError extends TypeError, ValueError extends TypeError, StructuralIssue extends RecordStructuralIssue> extends TypeError<"Record"> {
5609
- readonly reason: {
5610
- readonly kind: "Entries";
5611
- readonly issues: NonEmptyReadonlyArray<RecordKeyIssue<KeyError> | RecordValueIssue<ValueError> | StructuralIssue>;
5612
- };
5613
- }
5614
5744
  /**
5615
5745
  * An optional property used to construct an {@link object} Type.
5616
5746
  *
@@ -5789,32 +5919,142 @@ interface RuntimeDefaultOperations {
5789
5919
  readonly createObject: (props: ObjectProps, record: RuntimeRecordTypeNode | undefined) => ObjectTypeNode;
5790
5920
  readonly partial: (type: RuntimeTypeNode) => OptionalProperty<TypeNode>;
5791
5921
  }
5922
+ /**
5923
+ * The {@link Type} returned by {@link object}.
5924
+ *
5925
+ * @group Objects
5926
+ */
5927
+ export type ObjectType<Props extends ObjectProps, Rest extends ObjectRecordTypeNode | undefined = undefined> = Props extends ObjectValueProps ? Rest extends ObjectRecordTypeNode ? ObjectWithRecordType<Props, Rest> : StrictObjectType<Props> : DefaultObjectType<Props, Rest>;
5792
5928
  /**
5793
5929
  * Properties used to construct an {@link object} Type.
5794
5930
  *
5795
5931
  * @group Objects
5796
5932
  */
5797
5933
  export type ObjectProps = Readonly<Record<string, TypeNode | OptionalProperty<TypeNode> | WithDefaultProperty<TypeNode, unknown, "replace" | "preserve">>>;
5798
- type ObjectValueProps = Readonly<Record<string, TypeNode | OptionalProperty<TypeNode>>>;
5799
- type ObjectProperty = ObjectProps[string];
5800
5934
  /**
5801
- * Plain object {@link Type}.
5935
+ * An error returned while validating an {@link object} and its properties.
5802
5936
  *
5803
- * Use `object(props)` for objects with fixed property names. Properties are
5804
- * required unless wrapped with {@link optional}. An optional property may be
5805
- * absent, but a present value is still validated and does not implicitly accept
5806
- * `undefined`. Wrapping an optional property with {@link withDefault} keeps the
5807
- * input optional and makes the decoded output required. A default for a
5808
- * nullable or undefined-accepting Type alone does not make the property
5809
- * optional.
5937
+ * Declare required properties as required keys and optional properties as
5938
+ * optional keys. Object adds its structural property errors automatically, so
5939
+ * each value is only the error returned by that property's Type. The interface
5940
+ * can be extended by recursive error declarations.
5810
5941
  *
5811
- * Without a second argument, `fromUnknown` rejects additional properties. Pass
5812
- * a {@link record} with the predefined {@link String} key Type to validate and
5813
- * preserve additional string-keyed properties.
5942
+ * @group Objects
5943
+ */
5944
+ export interface ObjectError<Errors extends {
5945
+ readonly [Key in keyof Errors]: TypeError | undefined;
5946
+ } = Readonly<Record<string, TypeError>>, RestError extends TypeError = ObjectExcessPropertyError> extends TypeError<"Object"> {
5947
+ readonly reason: ObjectNotObjectError["reason"] | ObjectUnexpectedPrototypeError["reason"] | ObjectPropertiesError<ObjectStructuralPropertyErrors<Errors>, RestError>["reason"];
5948
+ }
5949
+ /**
5950
+ * An error returned when a required {@link object} property is absent.
5814
5951
  *
5815
- * `fromUnknown` requires a plain object. Plain object Types model only own
5816
- * enumerable data properties, so Object prototype properties neither satisfy
5817
- * required properties nor make optional properties present. This keeps Outputs
5952
+ * `ObjectMissingProperty` is reserved for absent required properties. Property
5953
+ * {@link Type | Types} must use another error tag.
5954
+ *
5955
+ * @group Objects
5956
+ */
5957
+ export interface ObjectMissingPropertyError extends TypeError<"ObjectMissingProperty"> {
5958
+ }
5959
+ /**
5960
+ * An error returned when a present {@link object} property is not represented as
5961
+ * an enumerable data property.
5962
+ *
5963
+ * `ObjectPropertyAccess` is reserved for this structural failure. Property
5964
+ * {@link Type | Types} must use another error tag.
5965
+ *
5966
+ * @group Objects
5967
+ */
5968
+ export interface ObjectPropertyAccessError extends TypeError<"ObjectPropertyAccess"> {
5969
+ readonly reason: "Accessor" | "NonEnumerable";
5970
+ }
5971
+ /**
5972
+ * An error returned when an {@link object} input is not an object.
5973
+ *
5974
+ * @group Objects
5975
+ */
5976
+ export interface ObjectNotObjectError extends TypeError<"Object"> {
5977
+ readonly reason: {
5978
+ readonly kind: "NotObject";
5979
+ readonly value: unknown;
5980
+ };
5981
+ }
5982
+ /**
5983
+ * An error returned when an {@link object} input falls outside its supported
5984
+ * plain-object prototype boundary.
5985
+ *
5986
+ * Object Types use the realm-neutral structural heuristic described by
5987
+ * {@link isPlainObject}. Values that do not satisfy it return this error instead
5988
+ * of having their prototype or inherited state discarded. `reason.value` is the
5989
+ * rejected object.
5990
+ *
5991
+ * @group Objects
5992
+ */
5993
+ export interface ObjectUnexpectedPrototypeError extends TypeError<"Object"> {
5994
+ readonly reason: {
5995
+ readonly kind: "UnexpectedPrototype";
5996
+ readonly value: object;
5997
+ };
5998
+ }
5999
+ /**
6000
+ * An error returned for an input property outside an Object Type's allowed key
6001
+ * domain.
6002
+ *
6003
+ * This includes a property not declared by an {@link object} schema and a symbol
6004
+ * property on the predefined {@link Object}. The property key locates this error
6005
+ * in the containing Object error map. `ObjectExcessProperty` is reserved for
6006
+ * this structural failure. Property {@link Type | Types} must use another error
6007
+ * tag.
6008
+ *
6009
+ * @group Objects
6010
+ */
6011
+ export interface ObjectExcessPropertyError extends TypeError<"ObjectExcessProperty"> {
6012
+ }
6013
+ /**
6014
+ * An error returned while validating the properties of an {@link object}.
6015
+ *
6016
+ * @group Objects
6017
+ */
6018
+ export interface ObjectPropertiesError<Errors extends {
6019
+ readonly [Key in keyof Errors]: TypeError | undefined;
6020
+ }, RestError extends TypeError = never> extends TypeError<"Object"> {
6021
+ readonly reason: {
6022
+ readonly kind: "Properties";
6023
+ readonly errors: Partial<Errors> & ([RestError] extends [never] ? unknown : ObjectUnknownPropertyErrors<Exclude<Errors[keyof Errors], undefined>, RestError>);
6024
+ };
6025
+ }
6026
+ /**
6027
+ * The `fromUnknown` error of an {@link object} Type without a {@link record}
6028
+ * rest.
6029
+ *
6030
+ * It has the shape of {@link ObjectError} with the structural property errors
6031
+ * already included in `Errors`.
6032
+ *
6033
+ * @group Objects
6034
+ */
6035
+ export interface StrictObjectFromUnknownError<Errors extends {
6036
+ readonly [Key in keyof Errors]: TypeError;
6037
+ }> extends TypeError<"Object"> {
6038
+ readonly reason: ObjectNotObjectError["reason"] | ObjectUnexpectedPrototypeError["reason"] | ObjectPropertiesError<Errors, ObjectExcessPropertyError>["reason"];
6039
+ }
6040
+ /**
6041
+ * Plain object {@link Type}.
6042
+ *
6043
+ * Use `object(props)` for objects with fixed property names. Properties are
6044
+ * required unless wrapped with {@link optional}. An optional property may be
6045
+ * absent, but a present value is still validated and does not implicitly accept
6046
+ * `undefined`. Wrapping an optional property with {@link withDefault} keeps the
6047
+ * input optional and makes the decoded output required. A default for a
6048
+ * nullable or undefined-accepting Type alone does not make the property
6049
+ * optional.
6050
+ *
6051
+ * Without a second argument, `fromUnknown` rejects additional properties. Pass
6052
+ * a {@link record} with the predefined {@link String} key Type to validate and
6053
+ * preserve additional string-keyed properties.
6054
+ *
6055
+ * `fromUnknown` requires a plain object. Plain object Types model only own
6056
+ * enumerable data properties, so Object prototype properties neither satisfy
6057
+ * required properties nor make optional properties present. This keeps Outputs
5818
6058
  * valid after ordinary object spread restores `Object.prototype`.
5819
6059
  *
5820
6060
  * The prototype must satisfy the realm-neutral structural heuristic described
@@ -5994,6 +6234,8 @@ export declare function object<const Props extends ObjectProps, const Rest exten
5994
6234
  ] extends [never] ? [] : [
5995
6235
  ValidationFailure<ObjectValidationError<Props> | ObjectRecordValidationError<Props, Rest>>
5996
6236
  ]): ObjectType<Props, Rest>;
6237
+ type ObjectValueProps = Readonly<Record<string, TypeNode | OptionalProperty<TypeNode>>>;
6238
+ type ObjectProperty = ObjectProps[string];
5997
6239
  interface ObjectTypeNode extends TypeNode {
5998
6240
  readonly name: "Object";
5999
6241
  readonly props: ObjectProps;
@@ -6032,12 +6274,6 @@ type ObjectRecordKeyTypeError = CompileTimeError<"Type", "Object Record key must
6032
6274
  type ObjectRecordInputTypeError = CompileTimeError<"Type", "Every declared property Type Input must extend the Object Record value Type Input.">;
6033
6275
  type ObjectRecordOutputTypeError = CompileTimeError<"Type", "Every declared property Type Output must extend the Object Record value Type Output.">;
6034
6276
  type ObjectRecordCanonicalInputTypeError = CompileTimeError<"Type", "Every declared property Type CanonicalInput must extend the Object Record value Type CanonicalInput.">;
6035
- /**
6036
- * The {@link Type} returned by {@link object}.
6037
- *
6038
- * @group Objects
6039
- */
6040
- export type ObjectType<Props extends ObjectProps, Rest extends ObjectRecordTypeNode | undefined = undefined> = Props extends ObjectValueProps ? Rest extends ObjectRecordTypeNode ? ObjectWithRecordType<Props, Rest> : StrictObjectType<Props> : DefaultObjectType<Props, Rest>;
6041
6277
  type ObjectValueType<Props extends ObjectValueProps, Rest extends ObjectRecordTypeNode | undefined> = Rest extends ObjectRecordTypeNode ? ObjectWithRecordType<Props, Rest> : StrictObjectType<Props>;
6042
6278
  type DefaultableObjectPropertyType<Property extends ObjectProperty> = Property extends WithDefaultProperty<infer T, infer Value, infer Strategy> ? Type<"WithDefault", T["Input"], WithDefaultOutput<T, Value, Strategy, "missing" | DefaultOriginal<T>>, never, T, InferErrors<T>, never, T["CanonicalInput"], false> : Property extends TypeNode | OptionalProperty<TypeNode> ? ObjectPropertyType<Property> : never;
6043
6279
  type DefaultInputProps<Props extends ObjectProps> = {
@@ -6093,8 +6329,14 @@ type ObjectWithRecordParents<Props extends ObjectValueProps, Rest extends Object
6093
6329
  type RootObjectProps<Props extends ObjectValueProps> = {
6094
6330
  readonly [Key in keyof Props]: Props[Key] extends OptionalProperty<infer T> ? OptionalProperty<RootType<T>> : Props[Key] extends TypeNode ? RootType<Props[Key]> : never;
6095
6331
  };
6096
- type RootObjectRecord<Rest extends ObjectRecordTypeNode> = RecordType<typeof String, RootType<Rest["value"]>>;
6097
- interface ObjectWithRecordReflection<Props extends ObjectValueProps, Rest extends ObjectRecordTypeNode> {
6332
+ type RootObjectRecord<Rest extends ObjectRecordTypeNode> = Rest["parent"] extends infer Parent extends ObjectRecordTypeNode ? Parent : Rest;
6333
+ /**
6334
+ * The declared properties and {@link record} rest of an {@link object} Type
6335
+ * created with a Record.
6336
+ *
6337
+ * @group Objects
6338
+ */
6339
+ export interface ObjectWithRecordReflection<Props extends ObjectValueProps, Rest extends ObjectRecordTypeNode> {
6098
6340
  readonly props: Readonly<Props>;
6099
6341
  readonly record: Rest;
6100
6342
  }
@@ -6108,103 +6350,6 @@ type StrictObjectFromUnknownPropertyErrors<Props extends ObjectValueProps> = {
6108
6350
  } & {
6109
6351
  readonly [Key in OptionalObjectKeys<Props>]: Props[Key][typeof errorsSymbol] | ObjectPropertyAccessError;
6110
6352
  };
6111
- /**
6112
- * An error returned when a required {@link object} property is absent.
6113
- *
6114
- * `ObjectMissingProperty` is reserved for absent required properties. Property
6115
- * {@link Type | Types} must use another error tag.
6116
- *
6117
- * @group Objects
6118
- */
6119
- export interface ObjectMissingPropertyError extends TypeError<"ObjectMissingProperty"> {
6120
- }
6121
- /**
6122
- * An error returned when a present {@link object} property is not represented as
6123
- * an enumerable data property.
6124
- *
6125
- * `ObjectPropertyAccess` is reserved for this structural failure. Property
6126
- * {@link Type | Types} must use another error tag.
6127
- *
6128
- * @group Objects
6129
- */
6130
- export interface ObjectPropertyAccessError extends TypeError<"ObjectPropertyAccess"> {
6131
- readonly reason: "Accessor" | "NonEnumerable";
6132
- }
6133
- /**
6134
- * An error returned when an {@link object} input is not an object.
6135
- *
6136
- * @group Objects
6137
- */
6138
- export interface ObjectNotObjectError extends TypeError<"Object"> {
6139
- readonly reason: {
6140
- readonly kind: "NotObject";
6141
- readonly value: unknown;
6142
- };
6143
- }
6144
- /**
6145
- * An error returned when an {@link object} input falls outside its supported
6146
- * plain-object prototype boundary.
6147
- *
6148
- * Object Types use the realm-neutral structural heuristic described by
6149
- * {@link isPlainObject}. Values that do not satisfy it return this error instead
6150
- * of having their prototype or inherited state discarded. `reason.value` is the
6151
- * rejected object.
6152
- *
6153
- * @group Objects
6154
- */
6155
- export interface ObjectUnexpectedPrototypeError extends TypeError<"Object"> {
6156
- readonly reason: {
6157
- readonly kind: "UnexpectedPrototype";
6158
- readonly value: object;
6159
- };
6160
- }
6161
- /**
6162
- * An error returned for an input property outside an Object Type's allowed key
6163
- * domain.
6164
- *
6165
- * This includes a property not declared by an {@link object} schema and a symbol
6166
- * property on the predefined {@link Object}. The property key locates this error
6167
- * in the containing Object error map. `ObjectExcessProperty` is reserved for
6168
- * this structural failure. Property {@link Type | Types} must use another error
6169
- * tag.
6170
- *
6171
- * @group Objects
6172
- */
6173
- export interface ObjectExcessPropertyError extends TypeError<"ObjectExcessProperty"> {
6174
- }
6175
- /**
6176
- * An error returned while validating an {@link object} and its properties.
6177
- *
6178
- * Declare required properties as required keys and optional properties as
6179
- * optional keys. Object adds its structural property errors automatically, so
6180
- * each value is only the error returned by that property's Type. The interface
6181
- * can be extended by recursive error declarations.
6182
- *
6183
- * @group Objects
6184
- */
6185
- export interface ObjectError<Errors extends {
6186
- readonly [Key in keyof Errors]: TypeError | undefined;
6187
- } = Readonly<Record<string, TypeError>>, RestError extends TypeError = ObjectExcessPropertyError> extends TypeError<"Object"> {
6188
- readonly reason: ObjectNotObjectError["reason"] | ObjectUnexpectedPrototypeError["reason"] | ObjectPropertiesError<ObjectStructuralPropertyErrors<Errors>, RestError>["reason"];
6189
- }
6190
- /**
6191
- * An error returned while validating the properties of an {@link object}.
6192
- *
6193
- * @group Objects
6194
- */
6195
- export interface ObjectPropertiesError<Errors extends {
6196
- readonly [Key in keyof Errors]: TypeError | undefined;
6197
- }, RestError extends TypeError = never> extends TypeError<"Object"> {
6198
- readonly reason: {
6199
- readonly kind: "Properties";
6200
- readonly errors: Partial<Errors> & ([RestError] extends [never] ? unknown : ObjectUnknownPropertyErrors<Exclude<Errors[keyof Errors], undefined>, RestError>);
6201
- };
6202
- }
6203
- interface StrictObjectFromUnknownError<Errors extends {
6204
- readonly [Key in keyof Errors]: TypeError;
6205
- }> extends TypeError<"Object"> {
6206
- readonly reason: ObjectNotObjectError["reason"] | ObjectUnexpectedPrototypeError["reason"] | ObjectPropertiesError<Errors, ObjectExcessPropertyError>["reason"];
6207
- }
6208
6353
  type ObjectStructuralPropertyErrors<Errors extends {
6209
6354
  readonly [Key in keyof Errors]: TypeError | undefined;
6210
6355
  }> = {
@@ -6216,6 +6361,14 @@ type ObjectFromParentError<Errors extends {
6216
6361
  type ObjectUnknownPropertyErrors<Error extends TypeError, RestError extends TypeError> = Readonly<Record<PropertyKey, Error | RestError | undefined>>;
6217
6362
  type ObjectRestFromUnknownError<Rest extends ObjectRecordTypeNode | undefined> = Rest extends ObjectRecordTypeNode ? ObjectPropertyAccessError | RecordEntriesErrorValue<TypeOfError<"String">, InferErrors<Rest["value"]>, never> : ObjectExcessPropertyError;
6218
6363
  type ObjectRestFromParentError<Rest extends ObjectRecordTypeNode | undefined> = Rest extends ObjectRecordTypeNode ? RecordEntriesError<never, TypeFromError<Rest["value"]>, never> : never;
6364
+ /**
6365
+ * Maps every required object property Type to an optional property.
6366
+ *
6367
+ * @group Objects
6368
+ */
6369
+ export type PartialObjectProps<Props extends ObjectProps> = {
6370
+ readonly [Key in keyof Props]: Props[Key] extends WithDefaultProperty<infer T, infer Value, infer Strategy> ? OptionalProperty<WithDefaultType<T, Value, Strategy>> : Props[Key] extends OptionalProperty<TypeNode> ? Props[Key] : Props[Key] extends TypeNode ? OptionalProperty<Props[Key]> : never;
6371
+ };
6219
6372
  /**
6220
6373
  * Object {@link Type} with every property optional.
6221
6374
  *
@@ -6246,12 +6399,13 @@ type ObjectRestFromParentError<Rest extends ObjectRecordTypeNode | undefined> =
6246
6399
  */
6247
6400
  export declare const partial: <const Props extends ObjectProps>(props: Props, ..._validation: [ObjectValidationError<Props>] extends [never] ? [] : [ValidationFailure<ObjectValidationError<Props>>]) => ObjectType<PartialObjectProps<Props>>;
6248
6401
  /**
6249
- * Maps every required object property Type to an optional property.
6402
+ * Maps object properties whose Union Type includes {@link Null} to optional
6403
+ * properties.
6250
6404
  *
6251
6405
  * @group Objects
6252
6406
  */
6253
- export type PartialObjectProps<Props extends ObjectProps> = {
6254
- readonly [Key in keyof Props]: Props[Key] extends WithDefaultProperty<infer T, infer Value, infer Strategy> ? OptionalProperty<WithDefaultType<T, Value, Strategy>> : Props[Key] extends OptionalProperty<TypeNode> ? Props[Key] : Props[Key] extends TypeNode ? OptionalProperty<Props[Key]> : never;
6407
+ export type NullableToOptionalProps<Props extends ObjectProps> = {
6408
+ readonly [Key in keyof Props]: Props[Key] extends OptionalProperty<TypeNode> ? Props[Key] : Props[Key] extends UnionType<infer Members> ? typeof Null extends Members[number] ? OptionalProperty<Props[Key]> : Props[Key] : Props[Key];
6255
6409
  };
6256
6410
  /**
6257
6411
  * Object {@link Type} making every property whose Union Type includes
@@ -6286,15 +6440,6 @@ export type PartialObjectProps<Props extends ObjectProps> = {
6286
6440
  * @group Objects
6287
6441
  */
6288
6442
  export declare const nullableToOptional: <const Props extends ObjectProps>(props: Props, ..._validation: [ObjectValidationError<Props>] extends [never] ? [] : [ValidationFailure<ObjectValidationError<Props>>]) => ObjectType<NullableToOptionalProps<Props>>;
6289
- /**
6290
- * Maps object properties whose Union Type includes {@link Null} to optional
6291
- * properties.
6292
- *
6293
- * @group Objects
6294
- */
6295
- export type NullableToOptionalProps<Props extends ObjectProps> = {
6296
- readonly [Key in keyof Props]: Props[Key] extends OptionalProperty<TypeNode> ? Props[Key] : Props[Key] extends UnionType<infer Members> ? typeof Null extends Members[number] ? OptionalProperty<Props[Key]> : Props[Key] : Props[Key];
6297
- };
6298
6443
  /**
6299
6444
  * Object {@link Type} without the selected declared properties.
6300
6445
  *
@@ -6332,6 +6477,16 @@ export interface ObjectKeysType<Key extends TypeNode, T extends TypeNode & {
6332
6477
  readonly output: T;
6333
6478
  readonly [reflectedTypesSymbol]?: Key | T;
6334
6479
  }
6480
+ /**
6481
+ * An error from the externally named object decoded by {@link objectKeys}.
6482
+ *
6483
+ * @group Objects
6484
+ */
6485
+ export interface ObjectKeysError<T extends TypeNode & {
6486
+ readonly props: ObjectProps;
6487
+ }> extends TypeError<"ObjectKeys">, TransparentTypeError {
6488
+ readonly error: ObjectError<Readonly<Record<string, T["props"][keyof T["props"]][typeof errorsSymbol] | ObjectMissingPropertyError | ObjectExcessPropertyError>>>;
6489
+ }
6335
6490
  /**
6336
6491
  * Renames a strict {@link object} Type's encoded keys using a string codec.
6337
6492
  *
@@ -6386,16 +6541,6 @@ export declare const objectKeys: <Key extends ConcreteTypeNode & {
6386
6541
  readonly props: ObjectProps;
6387
6542
  readonly record?: never;
6388
6543
  }>(type: T & ValidateOutput<T>) => ObjectKeysType<Key, T>;
6389
- /**
6390
- * An error from the externally named object decoded by {@link objectKeys}.
6391
- *
6392
- * @group Objects
6393
- */
6394
- export interface ObjectKeysError<T extends TypeNode & {
6395
- readonly props: ObjectProps;
6396
- }> extends TypeError<"ObjectKeys">, TransparentTypeError {
6397
- readonly error: ObjectError<Readonly<Record<string, T["props"][keyof T["props"]][typeof errorsSymbol] | ObjectMissingPropertyError | ObjectExcessPropertyError>>>;
6398
- }
6399
6544
  /**
6400
6545
  * Creates a {@link Type} for {@link Result} values.
6401
6546
  *
@@ -6411,53 +6556,145 @@ export interface ObjectKeysError<T extends TypeNode & {
6411
6556
  * assertOk,
6412
6557
  * NonNegativeInt,
6413
6558
  * String,
6414
- * object,
6415
- * result,
6559
+ * object,
6560
+ * result,
6561
+ * typed,
6562
+ * } from "@evolu/common";
6563
+ *
6564
+ * const SyncResponse = result(
6565
+ * object({ timestamp: NonNegativeInt }),
6566
+ * typed("SyncFailed", { message: String }),
6567
+ * );
6568
+ *
6569
+ * const validated = SyncResponse.fromUnknown({
6570
+ * ok: true,
6571
+ * value: { timestamp: 42 },
6572
+ * });
6573
+ *
6574
+ * assertOk(validated, { ok: true, value: { timestamp: 42 } });
6575
+ * assertOk(validated.value, { timestamp: 42 });
6576
+ * ```
6577
+ *
6578
+ * @group Results
6579
+ */
6580
+ export declare function result<OkType extends ConcreteTypeNode, ErrorType extends ConcreteTypeNode>(okType: ValidateElement<OkType>, errorType: ValidateElement<ErrorType>): DiscriminatedUnionType<"ok", readonly [
6581
+ ObjectType<{
6582
+ readonly ok: LiteralType<true>;
6583
+ readonly value: OkType;
6584
+ }>,
6585
+ ObjectType<{
6586
+ readonly ok: LiteralType<false>;
6587
+ readonly error: ErrorType;
6588
+ }>
6589
+ ]>;
6590
+ /**
6591
+ * A {@link result} Type for `Result<unknown, unknown>`.
6592
+ *
6593
+ * Use this when only the Result structure must be validated, while its value
6594
+ * and error remain intentionally unknown.
6595
+ *
6596
+ * @group Results
6597
+ */
6598
+ export declare const UnknownResult: DiscriminatedUnionType<"ok", readonly [StrictObjectType<{
6599
+ readonly ok: LiteralType<true>;
6600
+ readonly value: Type<"Unknown", unknown, unknown, never, null, never, never, unknown, true>;
6601
+ }>, StrictObjectType<{
6602
+ readonly ok: LiteralType<false>;
6603
+ readonly error: Type<"Unknown", unknown, unknown, never, null, never, never, unknown, true>;
6604
+ }>]>;
6605
+ export type UnknownResult = typeof UnknownResult.Output;
6606
+ /**
6607
+ * The {@link ObjectType} returned by {@link typed}.
6608
+ *
6609
+ * @group Discriminated unions
6610
+ */
6611
+ export type TypedType<Tag extends TypeName, Props extends ObjectProps = Readonly<Record<never, never>>, Rest extends ObjectRecordTypeNode | undefined = undefined> = ObjectType<TypedProps<Tag, Props>, Rest>;
6612
+ /**
6613
+ * A TypeScript interface with a literal `type` property.
6614
+ *
6615
+ * Use `Typed` for both domain objects in discriminated unions and plain domain
6616
+ * errors returned by {@link Result}. Name a domain error interface `XError`.
6617
+ * When `X` already describes a failure, use `X` for its `type` discriminant
6618
+ * because `Error` describes the interface's role rather than the runtime error
6619
+ * kind. Keep `Error` when it is needed to make the discriminant unambiguous,
6620
+ * such as `TimeoutError`.
6621
+ *
6622
+ * Typed unions model mutually exclusive states as separate variants instead of
6623
+ * combinations of flags and optional properties. TypeScript narrows a union by
6624
+ * its literal `type` property. To enforce exhaustive handling, return from
6625
+ * every case of a value-producing switch or assert that the remaining value is
6626
+ * `never` in the `default` case of a side-effecting switch.
6627
+ *
6628
+ * ### Example
6629
+ *
6630
+ * ```ts
6631
+ * import {
6632
+ * assertErr,
6633
+ * assertOk,
6634
+ * err,
6635
+ * ok,
6636
+ * type Result,
6637
+ * type Typed,
6638
+ * } from "@evolu/common";
6639
+ *
6640
+ * interface User extends Typed<"User"> {
6641
+ * readonly id: string;
6642
+ * }
6643
+ *
6644
+ * interface UserNotFoundError extends Typed<"UserNotFound"> {
6645
+ * readonly id: string;
6646
+ * }
6647
+ *
6648
+ * const getUser = (id: string): Result<User, UserNotFoundError> =>
6649
+ * id === "user-1"
6650
+ * ? ok({ type: "User", id })
6651
+ * : err({ type: "UserNotFound", id });
6652
+ *
6653
+ * assertOk(getUser("user-1"), { type: "User", id: "user-1" });
6654
+ * assertErr(getUser("missing"), { type: "UserNotFound", id: "missing" });
6655
+ * ```
6656
+ *
6657
+ * @group Discriminated unions
6658
+ */
6659
+ export interface Typed<Tag extends TypeName> {
6660
+ readonly type: Tag;
6661
+ }
6662
+ /**
6663
+ * Extracts members of a {@link Typed} Output union by their `type` literal.
6664
+ *
6665
+ * The requested tag is constrained to the union's actual discriminator values,
6666
+ * so a misspelling is a TypeScript error instead of silently producing
6667
+ * `never`.
6668
+ *
6669
+ * ### Example
6670
+ *
6671
+ * ```ts
6672
+ * import {
6673
+ * assertType,
6674
+ * String,
6675
+ * discriminatedUnion,
6416
6676
  * typed,
6677
+ * type ExtractTyped,
6417
6678
  * } from "@evolu/common";
6418
6679
  *
6419
- * const SyncResponse = result(
6420
- * object({ timestamp: NonNegativeInt }),
6421
- * typed("SyncFailed", { message: String }),
6422
- * );
6423
- *
6424
- * const validated = SyncResponse.fromUnknown({
6425
- * ok: true,
6426
- * value: { timestamp: 42 },
6427
- * });
6680
+ * const Create = typed("Create", { id: String });
6681
+ * const Delete = typed("Delete", { id: String });
6682
+ * const Message = discriminatedUnion(Create, Delete);
6683
+ * type Message = typeof Message.Output;
6428
6684
  *
6429
- * assertOk(validated, { ok: true, value: { timestamp: 42 } });
6430
- * assertOk(validated.value, { timestamp: 42 });
6431
- * ```
6685
+ * type CreateMessage = ExtractTyped<Message, "Create">;
6432
6686
  *
6433
- * @group Results
6434
- */
6435
- export declare function result<OkType extends ConcreteTypeNode, ErrorType extends ConcreteTypeNode>(okType: ValidateElement<OkType>, errorType: ValidateElement<ErrorType>): DiscriminatedUnionType<"ok", readonly [
6436
- ObjectType<{
6437
- readonly ok: LiteralType<true>;
6438
- readonly value: OkType;
6439
- }>,
6440
- ObjectType<{
6441
- readonly ok: LiteralType<false>;
6442
- readonly error: ErrorType;
6443
- }>
6444
- ]>;
6445
- /**
6446
- * A {@link result} Type for `Result<unknown, unknown>`.
6687
+ * assertType<CreateMessage, typeof Create.Output>();
6447
6688
  *
6448
- * Use this when only the Result structure must be validated, while its value
6449
- * and error remain intentionally unknown.
6689
+ * // @ts-expect-error "Cretae" is not a Message type.
6690
+ * type _Typo = ExtractTyped<Message, "Cretae">;
6691
+ * ```
6450
6692
  *
6451
- * @group Results
6693
+ * @group Discriminated unions
6452
6694
  */
6453
- export declare const UnknownResult: DiscriminatedUnionType<"ok", readonly [StrictObjectType<{
6454
- readonly ok: LiteralType<true>;
6455
- readonly value: Type<"Unknown", unknown, unknown, never, null, never, never, unknown, true>;
6456
- }>, StrictObjectType<{
6457
- readonly ok: LiteralType<false>;
6458
- readonly error: Type<"Unknown", unknown, unknown, never, null, never, never, unknown, true>;
6459
- }>]>;
6460
- export type UnknownResult = typeof UnknownResult.Output;
6695
+ export type ExtractTyped<Output extends Typed<TypeName>, Name extends Output["type"]> = Extract<Output, {
6696
+ readonly type: Name;
6697
+ }>;
6461
6698
  /**
6462
6699
  * Creates an {@link ObjectType} with a literal `type` property.
6463
6700
  *
@@ -6557,98 +6794,6 @@ export declare function typed<const Tag extends TypeName, const Props extends Ob
6557
6794
  ] extends [never] ? [] : [
6558
6795
  ValidationFailure<TypedValidationError<Props> | ObjectRecordValidationError<TypedProps<Tag, Props>, Rest>>
6559
6796
  ]): TypedType<Tag, Props, Rest extends ObjectRecordTypeNode ? Rest : never>;
6560
- /**
6561
- * A TypeScript interface with a literal `type` property.
6562
- *
6563
- * Use `Typed` for both domain objects in discriminated unions and plain domain
6564
- * errors returned by {@link Result}. Name a domain error interface `XError`.
6565
- * When `X` already describes a failure, use `X` for its `type` discriminant
6566
- * because `Error` describes the interface's role rather than the runtime error
6567
- * kind. Keep `Error` when it is needed to make the discriminant unambiguous,
6568
- * such as `TimeoutError`.
6569
- *
6570
- * Typed unions model mutually exclusive states as separate variants instead of
6571
- * combinations of flags and optional properties. TypeScript narrows a union by
6572
- * its literal `type` property. To enforce exhaustive handling, return from
6573
- * every case of a value-producing switch or assert that the remaining value is
6574
- * `never` in the `default` case of a side-effecting switch.
6575
- *
6576
- * ### Example
6577
- *
6578
- * ```ts
6579
- * import {
6580
- * assertErr,
6581
- * assertOk,
6582
- * err,
6583
- * ok,
6584
- * type Result,
6585
- * type Typed,
6586
- * } from "@evolu/common";
6587
- *
6588
- * interface User extends Typed<"User"> {
6589
- * readonly id: string;
6590
- * }
6591
- *
6592
- * const getUser = (id: string): Result<User, UserNotFoundError> =>
6593
- * id === "user-1"
6594
- * ? ok({ type: "User", id })
6595
- * : err({ type: "UserNotFound", id });
6596
- *
6597
- * interface UserNotFoundError extends Typed<"UserNotFound"> {
6598
- * readonly id: string;
6599
- * }
6600
- *
6601
- * assertOk(getUser("user-1"), { type: "User", id: "user-1" });
6602
- * assertErr(getUser("missing"), { type: "UserNotFound", id: "missing" });
6603
- * ```
6604
- *
6605
- * @group Discriminated unions
6606
- */
6607
- export interface Typed<Tag extends TypeName> {
6608
- readonly type: Tag;
6609
- }
6610
- /**
6611
- * Extracts members of a {@link Typed} Output union by their `type` literal.
6612
- *
6613
- * The requested tag is constrained to the union's actual discriminator values,
6614
- * so a misspelling is a TypeScript error instead of silently producing
6615
- * `never`.
6616
- *
6617
- * ### Example
6618
- *
6619
- * ```ts
6620
- * import {
6621
- * assertType,
6622
- * String,
6623
- * discriminatedUnion,
6624
- * typed,
6625
- * type ExtractTyped,
6626
- * } from "@evolu/common";
6627
- *
6628
- * const Create = typed("Create", { id: String });
6629
- * const Delete = typed("Delete", { id: String });
6630
- * const Message = discriminatedUnion(Create, Delete);
6631
- * type Message = typeof Message.Output;
6632
- *
6633
- * type CreateMessage = ExtractTyped<Message, "Create">;
6634
- *
6635
- * assertType<CreateMessage, typeof Create.Output>();
6636
- *
6637
- * // @ts-expect-error "Cretae" is not a Message type.
6638
- * type _Typo = ExtractTyped<Message, "Cretae">;
6639
- * ```
6640
- *
6641
- * @group Discriminated unions
6642
- */
6643
- export type ExtractTyped<Output extends Typed<TypeName>, Name extends Output["type"]> = Extract<Output, {
6644
- readonly type: Name;
6645
- }>;
6646
- /**
6647
- * The {@link ObjectType} returned by {@link typed}.
6648
- *
6649
- * @group Discriminated unions
6650
- */
6651
- export type TypedType<Tag extends TypeName, Props extends ObjectProps = Readonly<Record<never, never>>, Rest extends ObjectRecordTypeNode | undefined = undefined> = ObjectType<TypedProps<Tag, Props>, Rest>;
6652
6797
  type TypedProps<Tag extends TypeName, Props extends ObjectProps> = {
6653
6798
  readonly type: LiteralType<Tag>;
6654
6799
  } & Props;
@@ -6730,73 +6875,6 @@ export declare const UnknownNextResult: DiscriminatedUnionType<"ok", readonly [S
6730
6875
  }>>]>;
6731
6876
  }>]>;
6732
6877
  export type UnknownNextResult = typeof UnknownNextResult.Output;
6733
- /**
6734
- * Discriminated union {@link Type}.
6735
- *
6736
- * With no explicit key, the conventional `type` property created by
6737
- * {@link typed} is used. Pass a key first to discriminate
6738
- * {@link ObjectType | Object Types} using a different property.
6739
- *
6740
- * Every member must be an Object Type with a unique required string, number,
6741
- * bigint, or boolean {@link LiteralType} at the discriminator key. Unlike
6742
- * {@link union}, only the selected member is decoded, checked, or encoded. The
6743
- * Discriminated Union Input therefore narrows each member's discriminator from
6744
- * its widened Input to the exact literal that selects that member. Use
6745
- * `fromUnknown` when a value does not yet have that correlated Input type.
6746
- *
6747
- * ### Example
6748
- *
6749
- * ```ts
6750
- * import {
6751
- * assertOk,
6752
- * String,
6753
- * discriminatedUnion,
6754
- * typed,
6755
- * } from "@evolu/common";
6756
- *
6757
- * const Created = typed("Created", { id: String });
6758
- * const Deleted = typed("Deleted", { id: String });
6759
- * const Event = discriminatedUnion(Created, Deleted);
6760
- *
6761
- * assertOk(Event.fromUnknown({ type: "Created", id: "id" }), {
6762
- * type: "Created",
6763
- * id: "id",
6764
- * });
6765
- * ```
6766
- *
6767
- * @group Discriminated unions
6768
- */
6769
- export declare function discriminatedUnion<const Members extends DiscriminatedUnionMembers>(...members: Members & DiscriminatedUnionValidation<"type", Members>): DiscriminatedUnionType<"type", Members>;
6770
- /**
6771
- * Creates a Discriminated Union Type with an explicit discriminator key.
6772
- *
6773
- * ### Example
6774
- *
6775
- * ```ts
6776
- * import {
6777
- * assertOk,
6778
- * Number,
6779
- * String,
6780
- * discriminatedUnion,
6781
- * literal,
6782
- * object,
6783
- * } from "@evolu/common";
6784
- *
6785
- * const Added = object({ kind: literal("added"), value: String });
6786
- * const Removed = object({ kind: literal("removed"), id: Number });
6787
- * const Event = discriminatedUnion("kind", Added, Removed);
6788
- *
6789
- * assertOk(Event.fromUnknown({ kind: "added", value: "Evolu" }), {
6790
- * kind: "added",
6791
- * value: "Evolu",
6792
- * });
6793
- * assertOk(Event.fromUnknown({ kind: "removed", id: 1 }), {
6794
- * kind: "removed",
6795
- * id: 1,
6796
- * });
6797
- * ```
6798
- */
6799
- export declare function discriminatedUnion<const Key extends string, const Members extends DiscriminatedUnionMembers>(key: ValidateDiscriminatedUnionKey<Key>, ...members: Members & DiscriminatedUnionValidation<Key, Members>): DiscriminatedUnionType<Key, Members>;
6800
6878
  /**
6801
6879
  * The routed {@link Type} returned by {@link discriminatedUnion}.
6802
6880
  *
@@ -6861,19 +6939,86 @@ export interface DiscriminatedUnionDiscriminatorError<Key extends string = strin
6861
6939
  *
6862
6940
  * @group Discriminated unions
6863
6941
  */
6864
- export interface DiscriminatedUnionMemberIssue<Discriminator extends Literal = Literal, Error extends TypeError = TypeError> {
6865
- readonly kind: "Member";
6866
- readonly discriminator: Discriminator;
6867
- readonly error: Error;
6868
- }
6942
+ export interface DiscriminatedUnionMemberIssue<Discriminator extends Literal = Literal, Error extends TypeError = TypeError> {
6943
+ readonly kind: "Member";
6944
+ readonly discriminator: Discriminator;
6945
+ readonly error: Error;
6946
+ }
6947
+ /**
6948
+ * An error returned by the member selected by {@link discriminatedUnion}.
6949
+ *
6950
+ * @group Discriminated unions
6951
+ */
6952
+ export type DiscriminatedUnionMemberError<Issue extends DiscriminatedUnionMemberIssue = DiscriminatedUnionMemberIssue> = [Issue] extends [never] ? never : TypeError<"DiscriminatedUnion"> & {
6953
+ readonly reason: Issue;
6954
+ };
6955
+ /**
6956
+ * Discriminated union {@link Type}.
6957
+ *
6958
+ * With no explicit key, the conventional `type` property created by
6959
+ * {@link typed} is used. Pass a key first to discriminate
6960
+ * {@link ObjectType | Object Types} using a different property.
6961
+ *
6962
+ * Every member must be an Object Type with a unique required string, number,
6963
+ * bigint, or boolean {@link LiteralType} at the discriminator key. Unlike
6964
+ * {@link union}, only the selected member is decoded, checked, or encoded. The
6965
+ * Discriminated Union Input therefore narrows each member's discriminator from
6966
+ * its widened Input to the exact literal that selects that member. Use
6967
+ * `fromUnknown` when a value does not yet have that correlated Input type.
6968
+ *
6969
+ * ### Example
6970
+ *
6971
+ * ```ts
6972
+ * import {
6973
+ * assertOk,
6974
+ * String,
6975
+ * discriminatedUnion,
6976
+ * typed,
6977
+ * } from "@evolu/common";
6978
+ *
6979
+ * const Created = typed("Created", { id: String });
6980
+ * const Deleted = typed("Deleted", { id: String });
6981
+ * const Event = discriminatedUnion(Created, Deleted);
6982
+ *
6983
+ * assertOk(Event.fromUnknown({ type: "Created", id: "id" }), {
6984
+ * type: "Created",
6985
+ * id: "id",
6986
+ * });
6987
+ * ```
6988
+ *
6989
+ * @group Discriminated unions
6990
+ */
6991
+ export declare function discriminatedUnion<const Members extends DiscriminatedUnionMembers>(...members: Members & DiscriminatedUnionValidation<"type", Members>): DiscriminatedUnionType<"type", Members>;
6869
6992
  /**
6870
- * An error returned by the member selected by {@link discriminatedUnion}.
6993
+ * Creates a Discriminated Union Type with an explicit discriminator key.
6871
6994
  *
6872
- * @group Discriminated unions
6995
+ * ### Example
6996
+ *
6997
+ * ```ts
6998
+ * import {
6999
+ * assertOk,
7000
+ * Number,
7001
+ * String,
7002
+ * discriminatedUnion,
7003
+ * literal,
7004
+ * object,
7005
+ * } from "@evolu/common";
7006
+ *
7007
+ * const Added = object({ kind: literal("added"), value: String });
7008
+ * const Removed = object({ kind: literal("removed"), id: Number });
7009
+ * const Event = discriminatedUnion("kind", Added, Removed);
7010
+ *
7011
+ * assertOk(Event.fromUnknown({ kind: "added", value: "Evolu" }), {
7012
+ * kind: "added",
7013
+ * value: "Evolu",
7014
+ * });
7015
+ * assertOk(Event.fromUnknown({ kind: "removed", id: 1 }), {
7016
+ * kind: "removed",
7017
+ * id: 1,
7018
+ * });
7019
+ * ```
6873
7020
  */
6874
- export type DiscriminatedUnionMemberError<Issue extends DiscriminatedUnionMemberIssue = DiscriminatedUnionMemberIssue> = [Issue] extends [never] ? never : TypeError<"DiscriminatedUnion"> & {
6875
- readonly reason: Issue;
6876
- };
7021
+ export declare function discriminatedUnion<const Key extends string, const Members extends DiscriminatedUnionMembers>(key: ValidateDiscriminatedUnionKey<Key>, ...members: Members & DiscriminatedUnionValidation<Key, Members>): DiscriminatedUnionType<Key, Members>;
6877
7022
  type DiscriminatedUnionObjectType = ObjectTypeNode & ConcreteTypeNode;
6878
7023
  type DiscriminatedUnionMembers = AtLeastTwoReadonlyArray<DiscriminatedUnionObjectType>;
6879
7024
  type DiscriminatedUnionLiteral = string | number | bigint | boolean;
@@ -6917,6 +7062,28 @@ type DiscriminatedUnionMembersTupleError = CompileTimeError<"Type", "Members mus
6917
7062
  type DiscriminatedUnionMemberConcreteTypeError = CompileTimeError<"Type", "Member must use one concrete Object Type node.">;
6918
7063
  type DiscriminatedUnionPropertyError<Key extends string> = CompileTimeError<"Type", `Property "${Key}" must be a required String, Number, BigInt, or Boolean Literal Type in every member.`>;
6919
7064
  type DiscriminatedUnionDuplicateValueError<Key extends string, Expected extends DiscriminatedUnionLiteral> = CompileTimeError<"Type", `Duplicate value "${Expected}" at property "${Key}".`>;
7065
+ /**
7066
+ * A deferred {@link Type} with an explicit recursive type declaration.
7067
+ *
7068
+ * A Lazy Type exposes one terminal input parent before its definition is
7069
+ * evaluated. Its `from` operation accepts its Output, while `from.parent`
7070
+ * performs the complete conversion from Input to Output. The resolved Type's
7071
+ * intermediate parent suffixes and constructor-specific reflection are
7072
+ * intentionally not exposed.
7073
+ *
7074
+ * `FromError` describes `from.parent` failures, `InputError` describes the
7075
+ * synthetic parent's unknown-input failures, and `Errors` describes the
7076
+ * complete `fromUnknown` failures. Keeping those channels explicit makes a
7077
+ * recursive declaration finite for TypeScript while preserving structured
7078
+ * errors at every boundary.
7079
+ *
7080
+ * @group Recursive
7081
+ */
7082
+ export interface LazyType<in out Input, in out Output, in out FromError extends TypeError, in out InputError extends TypeError, in out Errors extends TypeError, in out CanonicalInput extends Input = Input, in out UsesIdentityEncoding extends boolean = true> extends Type<"Lazy", Input, Output, FromError, Type<"Lazy", Input, Input, InputError, null, InputError, never, Input>, Errors, never, CanonicalInput, UsesIdentityEncoding> {
7083
+ readonly [lazyTypeSymbol]: true;
7084
+ /** Formats an error returned by any Lazy Type decoding operation. */
7085
+ readonly formatError: TypeErrorFormatter<Errors | FromError>;
7086
+ }
6920
7087
  /**
6921
7088
  * Creates a lazy {@link Type} for recursive definitions.
6922
7089
  *
@@ -6983,30 +7150,15 @@ type DiscriminatedUnionDuplicateValueError<Key extends string, Expected extends
6983
7150
  * @group Recursive
6984
7151
  */
6985
7152
  export declare function lazy<Target extends ConcreteTypeNode>(getType: Thunk<ValidateLazyTarget<Target>>): LazyType<Target["Input"], Target["Output"], TypeFromError<Target>, InferErrors<RootType<Target>>, InferErrors<Target>, CanonicalInputOf<Target>, IdentityEncodingOf<Target>>;
7153
+ type ValidateLazyTarget<Target extends ConcreteTypeNode> = IsUnion<Target> extends false ? Target : LazyTargetConcreteTypeError;
7154
+ type LazyTargetConcreteTypeError = CompileTimeError<"Type", "Lazy Type definition must return one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
6986
7155
  /**
6987
- * A deferred {@link Type} with an explicit recursive type declaration.
6988
- *
6989
- * A Lazy Type exposes one terminal input parent before its definition is
6990
- * evaluated. Its `from` operation accepts its Output, while `from.parent`
6991
- * performs the complete conversion from Input to Output. The resolved Type's
6992
- * intermediate parent suffixes and constructor-specific reflection are
6993
- * intentionally not exposed.
6994
- *
6995
- * `FromError` describes `from.parent` failures, `InputError` describes the
6996
- * synthetic parent's unknown-input failures, and `Errors` describes the
6997
- * complete `fromUnknown` failures. Keeping those channels explicit makes a
6998
- * recursive declaration finite for TypeScript while preserving structured
6999
- * errors at every boundary.
7156
+ * The root {@link Type} for Evolu {@link Data}.
7000
7157
  *
7001
- * @group Recursive
7158
+ * @group Base
7002
7159
  */
7003
- export interface LazyType<in out Input, in out Output, in out FromError extends TypeError, in out InputError extends TypeError, in out Errors extends TypeError, in out CanonicalInput extends Input = Input, in out UsesIdentityEncoding extends boolean = true> extends Type<"Lazy", Input, Output, FromError, Type<"Lazy", Input, Input, InputError, null, InputError, never, Input>, Errors, never, CanonicalInput, UsesIdentityEncoding> {
7004
- readonly [lazyTypeSymbol]: true;
7005
- /** Formats an error returned by any Lazy Type decoding operation. */
7006
- readonly formatError: TypeErrorFormatter<Errors | FromError>;
7160
+ export interface DataType extends Type<"Data", Data, Data, DataError, null, DataError, never, Data> {
7007
7161
  }
7008
- type ValidateLazyTarget<Target extends ConcreteTypeNode> = IsUnion<Target> extends false ? Target : LazyTargetConcreteTypeError;
7009
- type LazyTargetConcreteTypeError = CompileTimeError<"Type", "Lazy Type definition must return one concrete Type node. Pass a Union Type node instead of a union of Type nodes.">;
7010
7162
  /**
7011
7163
  * Evolu's recursive platform-independent structured-cloneable data domain.
7012
7164
  *
@@ -7052,46 +7204,17 @@ export type Data = undefined | null | string | number | bigint | boolean | Reado
7052
7204
  readonly [key: string]: Data;
7053
7205
  } | ReadonlySet<Data> | ReadonlyMap<Data, Data> | globalThis.Date | globalThis.Uint8Array;
7054
7206
  /**
7055
- * Returns whether a TypeScript type consists only of {@link Data}.
7056
- *
7057
- * Unlike `Value extends Data`, this recursively checks the declared properties
7058
- * of object types, so ordinary interfaces do not need a string index signature.
7059
- * This is a compile-time approximation of the Data domain; representation
7060
- * details such as prototypes and property descriptors still require the runtime
7061
- * {@link Data} Type.
7062
- *
7063
- * Recursive object types are supported.
7064
- *
7065
- * ### Example
7066
- *
7067
- * ```ts
7068
- * import { assertType, type IsData } from "@evolu/common";
7069
- *
7070
- * interface User {
7071
- * readonly name: string;
7072
- * readonly roles: ReadonlySet<string>;
7073
- * }
7074
- *
7075
- * interface Service {
7076
- * readonly run: () => void;
7077
- * }
7078
- *
7079
- * assertType<IsData<User>, true>();
7080
- * assertType<IsData<Service>, false>();
7081
- * ```
7207
+ * An error containing one or more issues found while validating a candidate as
7208
+ * {@link Data}.
7082
7209
  *
7083
7210
  * @group Base
7084
7211
  */
7085
- export type IsData<Value> = IsDataValue<Value, readonly []>;
7086
- type IsDataValue<Value, Seen extends ReadonlyArray<unknown>> = IsAny<Value> extends true ? false : unknown extends Value ? false : [Value] extends [never] ? true : false extends (Value extends unknown ? IsDataMember<Value, Seen> : never) ? false : true;
7087
- type IsAny<Value> = 0 extends 1 & Value ? true : false;
7088
- type IsDataMember<Value, Seen extends ReadonlyArray<unknown>> = IsSameType<Value, object> extends true ? false : IncludesSameType<Seen, Value> extends true ? true : Value extends void | null | string | number | bigint | boolean ? true : Value extends globalThis.Function ? false : Value extends globalThis.Date | globalThis.Uint8Array ? true : Value extends ReadonlyArray<infer Element> ? IsDataValue<Element, readonly [...Seen, Value]> : Value extends ReadonlySet<infer Element> ? IsDataValue<Element, readonly [...Seen, Value]> : Value extends ReadonlyMap<infer Key, infer MapValue> ? IsDataValue<Key | MapValue, readonly [...Seen, Value]> : Value extends object ? Extract<keyof Value, symbol> extends never ? IsDataObject<Value, readonly [...Seen, Value]> : false : false;
7089
- type IsDataObject<Value extends object, Seen extends ReadonlyArray<unknown>> = [
7090
- keyof Value
7091
- ] extends [never] ? false : false extends {
7092
- [Key in keyof Value]-?: IsDataValue<Value[Key], Seen>;
7093
- }[keyof Value] ? false : true;
7094
- type IncludesSameType<Values extends ReadonlyArray<unknown>, Value> = Values extends readonly [infer First, ...infer Rest] ? IsSameType<First, Value> extends true ? true : IncludesSameType<Rest, Value> : false;
7212
+ export interface DataError extends TypeError<"Data"> {
7213
+ readonly reason: {
7214
+ readonly kind: "Issues";
7215
+ readonly issues: NonEmptyReadonlyArray<DataIssue>;
7216
+ };
7217
+ }
7095
7218
  /**
7096
7219
  * One issue found while validating a candidate as {@link Data}.
7097
7220
  *
@@ -7127,25 +7250,6 @@ export type DataIssue = {
7127
7250
  readonly path: ReadonlyArray<PropertyKey>;
7128
7251
  readonly container: "Array" | "Set" | "Map";
7129
7252
  };
7130
- /**
7131
- * An error containing one or more issues found while validating a candidate as
7132
- * {@link Data}.
7133
- *
7134
- * @group Base
7135
- */
7136
- export interface DataError extends TypeError<"Data"> {
7137
- readonly reason: {
7138
- readonly kind: "Issues";
7139
- readonly issues: NonEmptyReadonlyArray<DataIssue>;
7140
- };
7141
- }
7142
- /**
7143
- * The root {@link Type} for Evolu {@link Data}.
7144
- *
7145
- * @group Base
7146
- */
7147
- export interface DataType extends Type<"Data", Data, Data, DataError, null, DataError, never, Data> {
7148
- }
7149
7253
  /**
7150
7254
  * Root Type for {@link Data} values.
7151
7255
  *
@@ -7167,6 +7271,54 @@ export interface DataType extends Type<"Data", Data, Data, DataError, null, Data
7167
7271
  * @group Base
7168
7272
  */
7169
7273
  export declare const Data: DataType;
7274
+ /**
7275
+ * Returns whether a TypeScript type consists only of {@link Data}.
7276
+ *
7277
+ * Unlike `Value extends Data`, this recursively checks the declared properties
7278
+ * of object types, so ordinary interfaces do not need a string index signature.
7279
+ * This is a compile-time approximation of the Data domain; representation
7280
+ * details such as prototypes and property descriptors still require the runtime
7281
+ * {@link Data} Type.
7282
+ *
7283
+ * Recursive object types are supported.
7284
+ *
7285
+ * ### Example
7286
+ *
7287
+ * ```ts
7288
+ * import { assertType, type IsData } from "@evolu/common";
7289
+ *
7290
+ * interface User {
7291
+ * readonly name: string;
7292
+ * readonly roles: ReadonlySet<string>;
7293
+ * }
7294
+ *
7295
+ * interface Service {
7296
+ * readonly run: () => void;
7297
+ * }
7298
+ *
7299
+ * assertType<IsData<User>, true>();
7300
+ * assertType<IsData<Service>, false>();
7301
+ * ```
7302
+ *
7303
+ * @group Base
7304
+ */
7305
+ export type IsData<Value> = IsDataValue<Value, readonly []>;
7306
+ type IsDataValue<Value, Seen extends ReadonlyArray<unknown>> = IsAny<Value> extends true ? false : unknown extends Value ? false : [Value] extends [never] ? true : false extends (Value extends unknown ? IsDataMember<Value, Seen> : never) ? false : true;
7307
+ type IsAny<Value> = 0 extends 1 & Value ? true : false;
7308
+ type IsDataMember<Value, Seen extends ReadonlyArray<unknown>> = IsSameType<Value, object> extends true ? false : IncludesSameType<Seen, Value> extends true ? true : Value extends void | null | string | number | bigint | boolean ? true : Value extends globalThis.Function ? false : Value extends globalThis.Date | globalThis.Uint8Array ? true : Value extends ReadonlyArray<infer Element> ? IsDataValue<Element, readonly [...Seen, Value]> : Value extends ReadonlySet<infer Element> ? IsDataValue<Element, readonly [...Seen, Value]> : Value extends ReadonlyMap<infer Key, infer MapValue> ? IsDataValue<Key | MapValue, readonly [...Seen, Value]> : Value extends object ? Extract<keyof Value, symbol> extends never ? IsDataObject<Value, readonly [...Seen, Value]> : false : false;
7309
+ type IsDataObject<Value extends object, Seen extends ReadonlyArray<unknown>> = [
7310
+ keyof Value
7311
+ ] extends [never] ? false : false extends {
7312
+ [Key in keyof Value]-?: IsDataValue<Value[Key], Seen>;
7313
+ }[keyof Value] ? false : true;
7314
+ type IncludesSameType<Values extends ReadonlyArray<unknown>, Value> = Values extends readonly [infer First, ...infer Rest] ? IsSameType<First, Value> extends true ? true : IncludesSameType<Rest, Value> : false;
7315
+ /**
7316
+ * The exact root {@link Type} of in-memory JSON data values.
7317
+ *
7318
+ * @group JSON
7319
+ */
7320
+ export interface JsonValueType extends Type<"JsonValue", JsonValue, JsonValue, JsonValueError, null, JsonValueError, never, JsonValue> {
7321
+ }
7170
7322
  /**
7171
7323
  * A candidate JSON value before exact runtime validation.
7172
7324
  *
@@ -7213,6 +7365,18 @@ export type JsonArray = ReadonlyArray<JsonValue>;
7213
7365
  export interface JsonObject {
7214
7366
  readonly [key: string]: JsonValue;
7215
7367
  }
7368
+ /**
7369
+ * An error containing one or more issues found while validating a candidate as
7370
+ * an exact {@link JsonValue}.
7371
+ *
7372
+ * @group JSON
7373
+ */
7374
+ export interface JsonValueError extends TypeError<"JsonValue"> {
7375
+ readonly reason: {
7376
+ readonly kind: "Issues";
7377
+ readonly issues: NonEmptyReadonlyArray<JsonValueIssue>;
7378
+ };
7379
+ }
7216
7380
  /**
7217
7381
  * One issue found while validating a candidate as an exact {@link JsonValue}.
7218
7382
  *
@@ -7251,35 +7415,6 @@ export type JsonValueIssue = {
7251
7415
  readonly path: ReadonlyArray<string | number | symbol>;
7252
7416
  readonly ancestorPath: ReadonlyArray<string | number | symbol>;
7253
7417
  };
7254
- /**
7255
- * An error containing one or more issues found while validating a candidate as
7256
- * an exact {@link JsonValue}.
7257
- *
7258
- * @group JSON
7259
- */
7260
- export interface JsonValueError extends TypeError<"JsonValue"> {
7261
- readonly reason: {
7262
- readonly kind: "Issues";
7263
- readonly issues: NonEmptyReadonlyArray<JsonValueIssue>;
7264
- };
7265
- }
7266
- /**
7267
- * The exact root {@link Type} of in-memory JSON data values.
7268
- *
7269
- * @group JSON
7270
- */
7271
- export interface JsonValueType extends Type<"JsonValue", JsonValue, JsonValue, JsonValueError, null, JsonValueError, never, JsonValue> {
7272
- }
7273
- /**
7274
- * The exact top-level JSON object {@link Type}.
7275
- *
7276
- * @group JSON
7277
- */
7278
- export interface JsonObjectType extends Type<"Record", JsonObject, JsonObject, RecordError<TypeOfError<"String">, JsonValueError, never>, null, RecordError<TypeOfError<"String">, JsonValueError, never>, never, JsonObject> {
7279
- readonly [reflectedTypesSymbol]?: typeof String | JsonValueType;
7280
- readonly key: typeof String;
7281
- readonly value: JsonValueType;
7282
- }
7283
7418
  /**
7284
7419
  * An error returned when a string does not contain valid JSON text.
7285
7420
  *
@@ -7320,6 +7455,16 @@ export declare const JsonValue: JsonValueType;
7320
7455
  * @group JSON
7321
7456
  */
7322
7457
  export declare const JsonArray: ArrayType<JsonValueType>;
7458
+ /**
7459
+ * The exact top-level JSON object {@link Type}.
7460
+ *
7461
+ * @group JSON
7462
+ */
7463
+ export interface JsonObjectType extends Type<"Record", JsonObject, JsonObject, RecordError<TypeOfError<"String">, JsonValueError, never>, null, RecordError<TypeOfError<"String">, JsonValueError, never>, never, JsonObject> {
7464
+ readonly [reflectedTypesSymbol]?: typeof String | JsonValueType;
7465
+ readonly key: typeof String;
7466
+ readonly value: JsonValueType;
7467
+ }
7323
7468
  /**
7324
7469
  * Exact top-level JSON object {@link Type}.
7325
7470
  *