@evolu/common 6.0.1-preview.24 → 6.0.1-preview.26
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.
- package/dist/src/Assert.d.ts +0 -13
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +0 -15
- package/dist/src/Cache.d.ts +44 -0
- package/dist/src/Cache.d.ts.map +1 -0
- package/dist/src/Cache.js +52 -0
- package/dist/src/Evolu/Db.d.ts +6 -6
- package/dist/src/Evolu/Db.d.ts.map +1 -1
- package/dist/src/Evolu/Db.js +4 -0
- package/dist/src/Evolu/LocalAuth.d.ts +2 -2
- package/dist/src/Evolu/LocalAuth.d.ts.map +1 -1
- package/dist/src/Evolu/Owner.d.ts +116 -86
- package/dist/src/Evolu/Owner.d.ts.map +1 -1
- package/dist/src/Evolu/Owner.js +48 -45
- package/dist/src/Evolu/Relay.d.ts +6 -5
- package/dist/src/Evolu/Relay.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.js +40 -39
- package/dist/src/Evolu/Storage.d.ts +6 -11
- package/dist/src/Evolu/Storage.d.ts.map +1 -1
- package/dist/src/Evolu/Storage.js +30 -9
- package/dist/src/Evolu/Sync.d.ts +5 -5
- package/dist/src/Evolu/Sync.d.ts.map +1 -1
- package/dist/src/Evolu/Sync.js +3 -5
- package/dist/src/Evolu/Timestamp.d.ts +24 -0
- package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
- package/dist/src/Evolu/Timestamp.js +24 -0
- package/dist/src/Identicon.d.ts +35 -0
- package/dist/src/Identicon.d.ts.map +1 -0
- package/dist/src/Identicon.js +143 -0
- package/dist/src/ManyToManyMap.d.ts +0 -3
- package/dist/src/ManyToManyMap.d.ts.map +1 -1
- package/dist/src/Result.d.ts +13 -6
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Sqlite.d.ts +36 -1
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +56 -3
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +36 -0
- package/dist/src/Type.d.ts +73 -9
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +124 -22
- package/dist/src/Types.d.ts +1 -1
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +2 -7
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/package.json +1 -1
- package/src/Assert.ts +0 -19
- package/src/Cache.ts +85 -0
- package/src/Evolu/Db.ts +11 -7
- package/src/Evolu/LocalAuth.ts +19 -7
- package/src/Evolu/Owner.ts +140 -103
- package/src/Evolu/Relay.ts +52 -48
- package/src/Evolu/Storage.ts +47 -23
- package/src/Evolu/Sync.ts +11 -12
- package/src/Evolu/Timestamp.ts +24 -0
- package/src/Identicon.ts +197 -0
- package/src/ManyToManyMap.ts +0 -3
- package/src/Result.ts +13 -6
- package/src/Sqlite.ts +68 -5
- package/src/Task.ts +41 -0
- package/src/Type.ts +262 -27
- package/src/Types.ts +1 -1
- package/src/WebSocket.ts +6 -10
- package/src/index.ts +2 -0
package/src/Type.ts
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* {@link Result}) instead of throwing. We either get a safely typed value or a
|
|
6
6
|
* precise, composable error value telling us exactly why validation failed.
|
|
7
7
|
*
|
|
8
|
+
* Evolu Type supports [Standard Schema](https://standardschema.dev/) for
|
|
9
|
+
* interoperability with 40+ validation-compatible tools and frameworks.
|
|
10
|
+
*
|
|
8
11
|
* Why another validation library?
|
|
9
12
|
*
|
|
10
13
|
* - **Result-based error handling** – no exceptions for normal control flow.
|
|
@@ -196,7 +199,7 @@ export interface Type<
|
|
|
196
199
|
Parent = T,
|
|
197
200
|
/** The parent's error. */
|
|
198
201
|
ParentError extends TypeError = Error,
|
|
199
|
-
> {
|
|
202
|
+
> extends StandardSchemaV1<Input, T> {
|
|
200
203
|
readonly name: Name;
|
|
201
204
|
|
|
202
205
|
/**
|
|
@@ -250,7 +253,6 @@ export interface Type<
|
|
|
250
253
|
*
|
|
251
254
|
* - When you need to convert a validation result to a nullable value
|
|
252
255
|
* - When the error is not important and you just want the value or nothing
|
|
253
|
-
* - APIs that expect `T | null`
|
|
254
256
|
*
|
|
255
257
|
* ### Example
|
|
256
258
|
*
|
|
@@ -367,8 +369,6 @@ export interface Type<
|
|
|
367
369
|
readonly ParentError: ParentError;
|
|
368
370
|
|
|
369
371
|
/**
|
|
370
|
-
* Error | ParentError
|
|
371
|
-
*
|
|
372
372
|
* ### Example
|
|
373
373
|
*
|
|
374
374
|
* ```ts
|
|
@@ -458,7 +458,7 @@ export type InferParentError<A extends AnyType> =
|
|
|
458
458
|
: never;
|
|
459
459
|
|
|
460
460
|
/**
|
|
461
|
-
* Extracts all error types
|
|
461
|
+
* Extracts all error types from a {@link Type}.
|
|
462
462
|
*
|
|
463
463
|
* @category Utilities
|
|
464
464
|
*/
|
|
@@ -500,6 +500,7 @@ const createType = <
|
|
|
500
500
|
| "Parent"
|
|
501
501
|
| "ParentError"
|
|
502
502
|
| "Errors"
|
|
503
|
+
| "~standard"
|
|
503
504
|
>,
|
|
504
505
|
): Type<Name, T, Input, Error, Parent, ParentError> => ({
|
|
505
506
|
...definition,
|
|
@@ -515,6 +516,27 @@ const createType = <
|
|
|
515
516
|
Parent: undefined as unknown as Parent,
|
|
516
517
|
ParentError: undefined as unknown as ParentError,
|
|
517
518
|
Errors: undefined as unknown as Error | ParentError,
|
|
519
|
+
"~standard": {
|
|
520
|
+
version: 1,
|
|
521
|
+
vendor: "evolu",
|
|
522
|
+
validate: (value: unknown): StandardSchemaV1.Result<T> => {
|
|
523
|
+
const result = definition.fromUnknown(value);
|
|
524
|
+
if (result.ok) {
|
|
525
|
+
return { value: result.value };
|
|
526
|
+
}
|
|
527
|
+
cachedStandardSchemaFormatTypeError ??= createFormatTypeError();
|
|
528
|
+
return {
|
|
529
|
+
issues: typeErrorToStandardSchemaIssues(
|
|
530
|
+
result.error as TypeErrors<Error>,
|
|
531
|
+
cachedStandardSchemaFormatTypeError,
|
|
532
|
+
),
|
|
533
|
+
};
|
|
534
|
+
},
|
|
535
|
+
types: {
|
|
536
|
+
input: undefined as unknown as Input,
|
|
537
|
+
output: undefined as unknown as T,
|
|
538
|
+
},
|
|
539
|
+
},
|
|
518
540
|
});
|
|
519
541
|
|
|
520
542
|
/**
|
|
@@ -741,7 +763,7 @@ export interface InstanceOfType<T extends abstract new (...args: any) => any>
|
|
|
741
763
|
}
|
|
742
764
|
|
|
743
765
|
export const formatInstanceOfError = createTypeErrorFormatter<InstanceOfError>(
|
|
744
|
-
(error) => `
|
|
766
|
+
(error) => `The value ${error.value} is not an instance of ${error.ctor}.`,
|
|
745
767
|
);
|
|
746
768
|
|
|
747
769
|
/**
|
|
@@ -1005,7 +1027,7 @@ export interface CurrencyCodeError extends TypeError<"CurrencyCode"> {}
|
|
|
1005
1027
|
|
|
1006
1028
|
export const formatCurrencyCodeError =
|
|
1007
1029
|
createTypeErrorFormatter<CurrencyCodeError>(
|
|
1008
|
-
(error) => `Invalid currency code: ${error.value}
|
|
1030
|
+
(error) => `Invalid currency code: ${error.value}.`,
|
|
1009
1031
|
);
|
|
1010
1032
|
|
|
1011
1033
|
/**
|
|
@@ -1125,7 +1147,7 @@ export const trimmed: BrandFactory<"Trimmed", string, TrimmedError> = (
|
|
|
1125
1147
|
export interface TrimmedError extends TypeError<"Trimmed"> {}
|
|
1126
1148
|
|
|
1127
1149
|
export const formatTrimmedError = createTypeErrorFormatter<TrimmedError>(
|
|
1128
|
-
(error) => `
|
|
1150
|
+
(error) => `The value ${error.value} must be trimmed.`,
|
|
1129
1151
|
);
|
|
1130
1152
|
|
|
1131
1153
|
/**
|
|
@@ -1170,7 +1192,7 @@ export interface MinLengthError<Min extends number = number>
|
|
|
1170
1192
|
|
|
1171
1193
|
export const formatMinLengthError = createTypeErrorFormatter<MinLengthError>(
|
|
1172
1194
|
(error) =>
|
|
1173
|
-
`
|
|
1195
|
+
`The value ${error.value} does not meet the minimum length of ${error.min}.`,
|
|
1174
1196
|
);
|
|
1175
1197
|
|
|
1176
1198
|
/**
|
|
@@ -1200,7 +1222,8 @@ export interface MaxLengthError<Max extends number = number>
|
|
|
1200
1222
|
}
|
|
1201
1223
|
|
|
1202
1224
|
export const formatMaxLengthError = createTypeErrorFormatter<MaxLengthError>(
|
|
1203
|
-
(error) =>
|
|
1225
|
+
(error) =>
|
|
1226
|
+
`The value ${error.value} exceeds the maximum length of ${error.max}.`,
|
|
1204
1227
|
);
|
|
1205
1228
|
|
|
1206
1229
|
/**
|
|
@@ -1233,7 +1256,7 @@ export interface LengthError<Exact extends number = number>
|
|
|
1233
1256
|
|
|
1234
1257
|
export const formatLengthError = createTypeErrorFormatter<LengthError>(
|
|
1235
1258
|
(error) =>
|
|
1236
|
-
`
|
|
1259
|
+
`The value ${error.value} does not have the required length of ${error.exact}.`,
|
|
1237
1260
|
);
|
|
1238
1261
|
|
|
1239
1262
|
/** @category String */
|
|
@@ -1295,7 +1318,7 @@ export type Mnemonic = typeof Mnemonic.Type;
|
|
|
1295
1318
|
export interface MnemonicError extends TypeError<"Mnemonic"> {}
|
|
1296
1319
|
|
|
1297
1320
|
export const formatMnemonicError = createTypeErrorFormatter<MnemonicError>(
|
|
1298
|
-
(error) => `Invalid BIP39 mnemonic: ${error.value}
|
|
1321
|
+
(error) => `Invalid BIP39 mnemonic: ${error.value}.`,
|
|
1299
1322
|
);
|
|
1300
1323
|
|
|
1301
1324
|
/**
|
|
@@ -1334,7 +1357,7 @@ export interface RegexError<Name extends TypeName = TypeName>
|
|
|
1334
1357
|
|
|
1335
1358
|
export const formatRegexError = createTypeErrorFormatter<RegexError>(
|
|
1336
1359
|
(error) =>
|
|
1337
|
-
`
|
|
1360
|
+
`The value ${error.value} does not match the pattern for ${error.name}: ${error.pattern}.`,
|
|
1338
1361
|
);
|
|
1339
1362
|
|
|
1340
1363
|
/**
|
|
@@ -1400,7 +1423,7 @@ export type Base64Url = typeof Base64Url.Type;
|
|
|
1400
1423
|
export interface Base64UrlError extends TypeError<"Base64Url"> {}
|
|
1401
1424
|
|
|
1402
1425
|
export const formatBase64UrlError = createTypeErrorFormatter<Base64UrlError>(
|
|
1403
|
-
(error) => `
|
|
1426
|
+
(error) => `The value ${error.value} is not a valid Base64Url string.`,
|
|
1404
1427
|
);
|
|
1405
1428
|
|
|
1406
1429
|
const hasNodeBuffer = typeof globalThis.Buffer !== "undefined";
|
|
@@ -1553,7 +1576,7 @@ export type Id = typeof Id.Type;
|
|
|
1553
1576
|
export interface IdError extends TypeError<"Id"> {}
|
|
1554
1577
|
|
|
1555
1578
|
export const formatIdError = createTypeErrorFormatter<IdError>(
|
|
1556
|
-
(error) => `
|
|
1579
|
+
(error) => `The value ${error.value} is not a valid Id.`,
|
|
1557
1580
|
);
|
|
1558
1581
|
|
|
1559
1582
|
/**
|
|
@@ -1673,7 +1696,7 @@ export interface TableIdError<Table extends TypeName = TypeName>
|
|
|
1673
1696
|
}
|
|
1674
1697
|
|
|
1675
1698
|
export const formatTableIdError = createTypeErrorFormatter<TableIdError>(
|
|
1676
|
-
(error) => `Invalid ${error.
|
|
1699
|
+
(error) => `Invalid Id for table ${error.table}: ${error.value}.`,
|
|
1677
1700
|
);
|
|
1678
1701
|
|
|
1679
1702
|
/** Binary representation of an {@link Id}. */
|
|
@@ -1691,7 +1714,7 @@ export const idBytesToId = (idBytes: IdBytes): Id =>
|
|
|
1691
1714
|
uint8ArrayToBase64Url(idBytes) as unknown as Id;
|
|
1692
1715
|
|
|
1693
1716
|
/**
|
|
1694
|
-
* Positive number.
|
|
1717
|
+
* Positive number (> 0).
|
|
1695
1718
|
*
|
|
1696
1719
|
* ### Example
|
|
1697
1720
|
*
|
|
@@ -1714,11 +1737,11 @@ export const positive: BrandFactory<"Positive", number, PositiveError> = (
|
|
|
1714
1737
|
export interface PositiveError extends TypeError<"Positive"> {}
|
|
1715
1738
|
|
|
1716
1739
|
export const formatPositiveError = createTypeErrorFormatter<PositiveError>(
|
|
1717
|
-
(error) => `The value ${error.value}
|
|
1740
|
+
(error) => `The value ${error.value} must be positive (> 0).`,
|
|
1718
1741
|
);
|
|
1719
1742
|
|
|
1720
1743
|
/**
|
|
1721
|
-
* Negative number.
|
|
1744
|
+
* Negative number (< 0).
|
|
1722
1745
|
*
|
|
1723
1746
|
* ### Example
|
|
1724
1747
|
*
|
|
@@ -1738,11 +1761,11 @@ export const negative: BrandFactory<"Negative", number, NegativeError> = (
|
|
|
1738
1761
|
export interface NegativeError extends TypeError<"Negative"> {}
|
|
1739
1762
|
|
|
1740
1763
|
export const formatNegativeError = createTypeErrorFormatter<NegativeError>(
|
|
1741
|
-
(error) => `The value ${error.value}
|
|
1764
|
+
(error) => `The value ${error.value} must be negative (< 0).`,
|
|
1742
1765
|
);
|
|
1743
1766
|
|
|
1744
1767
|
/**
|
|
1745
|
-
* Non-positive number.
|
|
1768
|
+
* Non-positive number (≤ 0).
|
|
1746
1769
|
*
|
|
1747
1770
|
* ### Example
|
|
1748
1771
|
*
|
|
@@ -1767,11 +1790,11 @@ export interface NonPositiveError extends TypeError<"NonPositive"> {}
|
|
|
1767
1790
|
|
|
1768
1791
|
export const formatNonPositiveError =
|
|
1769
1792
|
createTypeErrorFormatter<NonPositiveError>(
|
|
1770
|
-
(error) => `The value ${error.value}
|
|
1793
|
+
(error) => `The value ${error.value} must be non-positive (≤ 0).`,
|
|
1771
1794
|
);
|
|
1772
1795
|
|
|
1773
1796
|
/**
|
|
1774
|
-
* Non-negative number.
|
|
1797
|
+
* Non-negative number (≥ 0).
|
|
1775
1798
|
*
|
|
1776
1799
|
* ### Example
|
|
1777
1800
|
*
|
|
@@ -1796,7 +1819,7 @@ export interface NonNegativeError extends TypeError<"NonNegative"> {}
|
|
|
1796
1819
|
|
|
1797
1820
|
export const formatNonNegativeError =
|
|
1798
1821
|
createTypeErrorFormatter<NonNegativeError>(
|
|
1799
|
-
(error) => `The value ${error.value}
|
|
1822
|
+
(error) => `The value ${error.value} must be non-negative (≥ 0).`,
|
|
1800
1823
|
);
|
|
1801
1824
|
|
|
1802
1825
|
/** @category Number */
|
|
@@ -1836,7 +1859,7 @@ export const int: BrandFactory<"Int", number, IntError> = (parent) =>
|
|
|
1836
1859
|
export interface IntError extends TypeError<"Int"> {}
|
|
1837
1860
|
|
|
1838
1861
|
export const formatIntError = createTypeErrorFormatter<IntError>(
|
|
1839
|
-
(error) => `The value ${error.value}
|
|
1862
|
+
(error) => `The value ${error.value} must be an integer.`,
|
|
1840
1863
|
);
|
|
1841
1864
|
|
|
1842
1865
|
/**
|
|
@@ -1982,7 +2005,7 @@ export const nonNaN: BrandFactory<"NonNaN", number, NonNaNError> = (parent) =>
|
|
|
1982
2005
|
export interface NonNaNError extends TypeError<"NonNaN"> {}
|
|
1983
2006
|
|
|
1984
2007
|
export const formatNonNaNError = createTypeErrorFormatter<NonNaNError>(
|
|
1985
|
-
(
|
|
2008
|
+
() => `The value must not be NaN.`,
|
|
1986
2009
|
);
|
|
1987
2010
|
|
|
1988
2011
|
/** @category Number */
|
|
@@ -2004,7 +2027,7 @@ export const finite: BrandFactory<"Finite", number, FiniteError> = (parent) =>
|
|
|
2004
2027
|
export interface FiniteError extends TypeError<"Finite"> {}
|
|
2005
2028
|
|
|
2006
2029
|
export const formatFiniteError = createTypeErrorFormatter<FiniteError>(
|
|
2007
|
-
(error) => `The value ${error.value}
|
|
2030
|
+
(error) => `The value ${error.value} must be finite.`,
|
|
2008
2031
|
);
|
|
2009
2032
|
|
|
2010
2033
|
/**
|
|
@@ -4045,8 +4068,220 @@ export const createFormatTypeError = <ExtraErrors extends TypeError = never>(
|
|
|
4045
4068
|
return formatUnionError(formatTypeError)(error);
|
|
4046
4069
|
case "Tuple":
|
|
4047
4070
|
return formatTupleError(formatTypeError)(error);
|
|
4071
|
+
default: {
|
|
4072
|
+
// Fallback for unknown error types
|
|
4073
|
+
const unknownError = error as TypeError;
|
|
4074
|
+
return `A value ${safelyStringifyUnknownValue(unknownError.value)} is not valid for type ${unknownError.type}.`;
|
|
4075
|
+
}
|
|
4048
4076
|
}
|
|
4049
4077
|
};
|
|
4050
4078
|
|
|
4051
4079
|
return formatTypeError;
|
|
4052
4080
|
};
|
|
4081
|
+
|
|
4082
|
+
/**
|
|
4083
|
+
* Converts an Evolu {@link TypeError} to Standard Schema V1 issues format.
|
|
4084
|
+
*
|
|
4085
|
+
* This function recursively converts Evolu's typed errors into the Standard
|
|
4086
|
+
* Schema issue format with proper path tracking for nested structures.
|
|
4087
|
+
*
|
|
4088
|
+
* @category Utilities
|
|
4089
|
+
*/
|
|
4090
|
+
export const typeErrorToStandardSchemaIssues = <
|
|
4091
|
+
ExtraErrors extends TypeError = never,
|
|
4092
|
+
>(
|
|
4093
|
+
error: TypeErrors<ExtraErrors>,
|
|
4094
|
+
formatTypeError: TypeErrorFormatter<TypeErrors<ExtraErrors>>,
|
|
4095
|
+
path: ReadonlyArray<PropertyKey> = [],
|
|
4096
|
+
): ReadonlyArray<StandardSchemaV1.Issue> => {
|
|
4097
|
+
if (error.type === "Array") {
|
|
4098
|
+
const arrayError = error as ArrayError;
|
|
4099
|
+
if (arrayError.reason.kind === "NotArray") {
|
|
4100
|
+
return [{ message: formatTypeError(error), path }];
|
|
4101
|
+
}
|
|
4102
|
+
return typeErrorToStandardSchemaIssues(
|
|
4103
|
+
arrayError.reason.error as TypeErrors<ExtraErrors>,
|
|
4104
|
+
formatTypeError,
|
|
4105
|
+
[...path, arrayError.reason.index],
|
|
4106
|
+
);
|
|
4107
|
+
}
|
|
4108
|
+
|
|
4109
|
+
if (error.type === "Object") {
|
|
4110
|
+
const objectError = error as ObjectError;
|
|
4111
|
+
if (
|
|
4112
|
+
objectError.reason.kind === "NotObject" ||
|
|
4113
|
+
objectError.reason.kind === "ExtraKeys"
|
|
4114
|
+
) {
|
|
4115
|
+
return [{ message: formatTypeError(error), path }];
|
|
4116
|
+
}
|
|
4117
|
+
const issues: Array<StandardSchemaV1.Issue> = [];
|
|
4118
|
+
for (const [key, propError] of Object.entries(objectError.reason.errors)) {
|
|
4119
|
+
issues.push(
|
|
4120
|
+
...typeErrorToStandardSchemaIssues(
|
|
4121
|
+
propError as TypeErrors<ExtraErrors>,
|
|
4122
|
+
formatTypeError,
|
|
4123
|
+
[...path, key],
|
|
4124
|
+
),
|
|
4125
|
+
);
|
|
4126
|
+
}
|
|
4127
|
+
return issues;
|
|
4128
|
+
}
|
|
4129
|
+
|
|
4130
|
+
if (error.type === "ObjectWithRecord") {
|
|
4131
|
+
const objectWithRecordError = error as ObjectWithRecordError;
|
|
4132
|
+
if (objectWithRecordError.reason.kind === "NotObject") {
|
|
4133
|
+
return [{ message: formatTypeError(error), path }];
|
|
4134
|
+
}
|
|
4135
|
+
if (
|
|
4136
|
+
objectWithRecordError.reason.kind === "IndexKey" ||
|
|
4137
|
+
objectWithRecordError.reason.kind === "IndexValue"
|
|
4138
|
+
) {
|
|
4139
|
+
return typeErrorToStandardSchemaIssues(
|
|
4140
|
+
objectWithRecordError.reason.error as TypeErrors<ExtraErrors>,
|
|
4141
|
+
formatTypeError,
|
|
4142
|
+
[...path, objectWithRecordError.reason.key as PropertyKey],
|
|
4143
|
+
);
|
|
4144
|
+
}
|
|
4145
|
+
const issues: Array<StandardSchemaV1.Issue> = [];
|
|
4146
|
+
for (const [key, propError] of Object.entries(
|
|
4147
|
+
objectWithRecordError.reason.errors,
|
|
4148
|
+
)) {
|
|
4149
|
+
issues.push(
|
|
4150
|
+
...typeErrorToStandardSchemaIssues(
|
|
4151
|
+
propError as TypeErrors<ExtraErrors>,
|
|
4152
|
+
formatTypeError,
|
|
4153
|
+
[...path, key],
|
|
4154
|
+
),
|
|
4155
|
+
);
|
|
4156
|
+
}
|
|
4157
|
+
return issues;
|
|
4158
|
+
}
|
|
4159
|
+
|
|
4160
|
+
if (error.type === "Record") {
|
|
4161
|
+
const recordError = error as RecordError;
|
|
4162
|
+
if (recordError.reason.kind === "NotRecord") {
|
|
4163
|
+
return [{ message: formatTypeError(error), path }];
|
|
4164
|
+
}
|
|
4165
|
+
return typeErrorToStandardSchemaIssues(
|
|
4166
|
+
recordError.reason.error as TypeErrors<ExtraErrors>,
|
|
4167
|
+
formatTypeError,
|
|
4168
|
+
[...path, recordError.reason.key as PropertyKey],
|
|
4169
|
+
);
|
|
4170
|
+
}
|
|
4171
|
+
|
|
4172
|
+
if (error.type === "Tuple") {
|
|
4173
|
+
const tupleError = error as TupleError;
|
|
4174
|
+
if (tupleError.reason.kind === "InvalidLength") {
|
|
4175
|
+
return [{ message: formatTypeError(error), path }];
|
|
4176
|
+
}
|
|
4177
|
+
return typeErrorToStandardSchemaIssues(
|
|
4178
|
+
tupleError.reason.error as TypeErrors<ExtraErrors>,
|
|
4179
|
+
formatTypeError,
|
|
4180
|
+
[...path, tupleError.reason.index],
|
|
4181
|
+
);
|
|
4182
|
+
}
|
|
4183
|
+
|
|
4184
|
+
if (error.type === "Union") {
|
|
4185
|
+
const unionError = error as UnionError;
|
|
4186
|
+
return unionError.errors.flatMap((err) =>
|
|
4187
|
+
typeErrorToStandardSchemaIssues(
|
|
4188
|
+
err as TypeErrors<ExtraErrors>,
|
|
4189
|
+
formatTypeError,
|
|
4190
|
+
path,
|
|
4191
|
+
),
|
|
4192
|
+
);
|
|
4193
|
+
}
|
|
4194
|
+
|
|
4195
|
+
if (error.type === "Brand") {
|
|
4196
|
+
const brandError = error as BrandWithoutRefineError<TypeName, TypeError>;
|
|
4197
|
+
if ("parentError" in brandError) {
|
|
4198
|
+
return typeErrorToStandardSchemaIssues(
|
|
4199
|
+
brandError.parentError as TypeErrors<ExtraErrors>,
|
|
4200
|
+
formatTypeError,
|
|
4201
|
+
path,
|
|
4202
|
+
);
|
|
4203
|
+
}
|
|
4204
|
+
return [{ message: formatTypeError(error), path }];
|
|
4205
|
+
}
|
|
4206
|
+
|
|
4207
|
+
return [{ message: formatTypeError(error), path }];
|
|
4208
|
+
};
|
|
4209
|
+
|
|
4210
|
+
/** The Standard Schema interface. */
|
|
4211
|
+
export interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
4212
|
+
/** The Standard Schema properties. */
|
|
4213
|
+
readonly "~standard": StandardSchemaV1.Props<Input, Output>;
|
|
4214
|
+
}
|
|
4215
|
+
|
|
4216
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
4217
|
+
export declare namespace StandardSchemaV1 {
|
|
4218
|
+
/** The Standard Schema properties interface. */
|
|
4219
|
+
export interface Props<Input = unknown, Output = Input> {
|
|
4220
|
+
/** The version number of the standard. */
|
|
4221
|
+
readonly version: 1;
|
|
4222
|
+
/** The vendor name of the schema library. */
|
|
4223
|
+
readonly vendor: string;
|
|
4224
|
+
/** Validates unknown input values. */
|
|
4225
|
+
readonly validate: (
|
|
4226
|
+
value: unknown,
|
|
4227
|
+
) => Result<Output> | Promise<Result<Output>>;
|
|
4228
|
+
/** Inferred types associated with the schema. */
|
|
4229
|
+
readonly types?: Types<Input, Output> | undefined;
|
|
4230
|
+
}
|
|
4231
|
+
|
|
4232
|
+
/** The result interface of the validate function. */
|
|
4233
|
+
export type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
4234
|
+
|
|
4235
|
+
/** The result interface if validation succeeds. */
|
|
4236
|
+
export interface SuccessResult<Output> {
|
|
4237
|
+
/** The typed output value. */
|
|
4238
|
+
readonly value: Output;
|
|
4239
|
+
/** The non-existent issues. */
|
|
4240
|
+
readonly issues?: undefined;
|
|
4241
|
+
}
|
|
4242
|
+
|
|
4243
|
+
/** The result interface if validation fails. */
|
|
4244
|
+
export interface FailureResult {
|
|
4245
|
+
/** The issues of failed validation. */
|
|
4246
|
+
readonly issues: ReadonlyArray<Issue>;
|
|
4247
|
+
}
|
|
4248
|
+
|
|
4249
|
+
/** The issue interface of the failure output. */
|
|
4250
|
+
export interface Issue {
|
|
4251
|
+
/** The error message of the issue. */
|
|
4252
|
+
readonly message: string;
|
|
4253
|
+
/** The path of the issue, if any. */
|
|
4254
|
+
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
|
4255
|
+
}
|
|
4256
|
+
|
|
4257
|
+
/** The path segment interface of the issue. */
|
|
4258
|
+
export interface PathSegment {
|
|
4259
|
+
/** The key representing a path segment. */
|
|
4260
|
+
readonly key: PropertyKey;
|
|
4261
|
+
}
|
|
4262
|
+
|
|
4263
|
+
/** The Standard Schema types interface. */
|
|
4264
|
+
export interface Types<Input = unknown, Output = Input> {
|
|
4265
|
+
/** The input type of the schema. */
|
|
4266
|
+
readonly input: Input;
|
|
4267
|
+
/** The output type of the schema. */
|
|
4268
|
+
readonly output: Output;
|
|
4269
|
+
}
|
|
4270
|
+
|
|
4271
|
+
/** Infers the input type of a Standard Schema. */
|
|
4272
|
+
export type InferInput<Schema extends StandardSchemaV1> = NonNullable<
|
|
4273
|
+
Schema["~standard"]["types"]
|
|
4274
|
+
>["input"];
|
|
4275
|
+
|
|
4276
|
+
/** Infers the output type of a Standard Schema. */
|
|
4277
|
+
export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<
|
|
4278
|
+
Schema["~standard"]["types"]
|
|
4279
|
+
>["output"];
|
|
4280
|
+
}
|
|
4281
|
+
|
|
4282
|
+
/**
|
|
4283
|
+
* Shared formatter cache for Standard Schema integration - avoids circular
|
|
4284
|
+
* dependency by lazily creating the formatter on first use rather than during
|
|
4285
|
+
* module initialization.
|
|
4286
|
+
*/
|
|
4287
|
+
let cachedStandardSchemaFormatTypeError: TypeErrorFormatter<any> | undefined;
|
package/src/Types.ts
CHANGED
|
@@ -79,7 +79,7 @@ export type NullablePartial<
|
|
|
79
79
|
export type IntentionalNever = never;
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
|
-
* String
|
|
82
|
+
* String, number, bigint, boolean, undefined, null
|
|
83
83
|
*
|
|
84
84
|
* https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types
|
|
85
85
|
*/
|
package/src/WebSocket.ts
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { assertNoErrorInCatch } from "./Assert.js";
|
|
8
7
|
import { constVoid } from "./Function.js";
|
|
9
8
|
import { err, ok, Result } from "./Result.js";
|
|
10
9
|
import { retry, RetryError, RetryOptions } from "./Task.js";
|
|
@@ -192,7 +191,7 @@ export const createWebSocket: CreateWebSocket = (
|
|
|
192
191
|
* - Is rejected when a connection is closed.
|
|
193
192
|
* - Is resolved when WebSocket is disposed().
|
|
194
193
|
*/
|
|
195
|
-
retry(
|
|
194
|
+
void retry(
|
|
196
195
|
{
|
|
197
196
|
...defaultRetryOptions,
|
|
198
197
|
...retryOptions,
|
|
@@ -222,6 +221,7 @@ export const createWebSocket: CreateWebSocket = (
|
|
|
222
221
|
? { type: "WebSocketConnectionError", event }
|
|
223
222
|
: { type: "WebSocketConnectError", event };
|
|
224
223
|
onError?.(error);
|
|
224
|
+
|
|
225
225
|
// Trigger reconnect only on WebSocketConnectError.
|
|
226
226
|
if (error.type === "WebSocketConnectError") {
|
|
227
227
|
resolve(err(error));
|
|
@@ -237,14 +237,10 @@ export const createWebSocket: CreateWebSocket = (
|
|
|
237
237
|
onMessage?.(event.data as string | ArrayBuffer | Blob);
|
|
238
238
|
};
|
|
239
239
|
}),
|
|
240
|
-
)(reconnectController)
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
})
|
|
245
|
-
.catch((error: unknown) => {
|
|
246
|
-
assertNoErrorInCatch("WebSocket retry", error);
|
|
247
|
-
});
|
|
240
|
+
)(reconnectController).then((result) => {
|
|
241
|
+
if (result.ok || result.error.type === "AbortError") return;
|
|
242
|
+
onError?.(result.error as WebSocketError);
|
|
243
|
+
});
|
|
248
244
|
|
|
249
245
|
return {
|
|
250
246
|
send: (data) => {
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from "./Assert.js";
|
|
|
3
3
|
export * from "./BigInt.js";
|
|
4
4
|
export * from "./Brand.js";
|
|
5
5
|
export * from "./Buffer.js";
|
|
6
|
+
export * from "./Cache.js";
|
|
6
7
|
export * from "./CallbackRegistry.js";
|
|
7
8
|
export * from "./Console.js";
|
|
8
9
|
export * from "./Crypto.js";
|
|
@@ -10,6 +11,7 @@ export * from "./Eq.js";
|
|
|
10
11
|
export * from "./Error.js";
|
|
11
12
|
export * from "./Evolu/Public.js";
|
|
12
13
|
export * from "./Function.js";
|
|
14
|
+
export * from "./Identicon.js";
|
|
13
15
|
export * from "./ManyToManyMap.js";
|
|
14
16
|
export * from "./Number.js";
|
|
15
17
|
export * from "./Object.js";
|