effect 3.19.2 → 3.19.4
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/PartitionedSemaphore/package.json +6 -0
- package/dist/cjs/Inspectable.js +86 -4
- package/dist/cjs/Inspectable.js.map +1 -1
- package/dist/cjs/ParseResult.js +1 -1
- package/dist/cjs/ParseResult.js.map +1 -1
- package/dist/cjs/PartitionedSemaphore.js +147 -0
- package/dist/cjs/PartitionedSemaphore.js.map +1 -0
- package/dist/cjs/Pretty.js +4 -3
- package/dist/cjs/Pretty.js.map +1 -1
- package/dist/cjs/Schema.js +15 -14
- package/dist/cjs/Schema.js.map +1 -1
- package/dist/cjs/SchemaAST.js +4 -3
- package/dist/cjs/SchemaAST.js.map +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/config.js +10 -9
- package/dist/cjs/internal/config.js.map +1 -1
- package/dist/cjs/internal/schema/errors.js +6 -5
- package/dist/cjs/internal/schema/errors.js.map +1 -1
- package/dist/cjs/internal/schema/util.js +3 -77
- package/dist/cjs/internal/schema/util.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/Inspectable.d.ts.map +1 -1
- package/dist/dts/PartitionedSemaphore.d.ts +76 -0
- package/dist/dts/PartitionedSemaphore.d.ts.map +1 -0
- package/dist/dts/Pretty.d.ts.map +1 -1
- package/dist/dts/Schema.d.ts.map +1 -1
- package/dist/dts/SchemaAST.d.ts.map +1 -1
- package/dist/dts/Types.d.ts +1 -1
- package/dist/dts/Types.d.ts.map +1 -1
- package/dist/dts/index.d.ts +5 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/esm/Inspectable.js +79 -2
- package/dist/esm/Inspectable.js.map +1 -1
- package/dist/esm/ParseResult.js +1 -1
- package/dist/esm/ParseResult.js.map +1 -1
- package/dist/esm/PartitionedSemaphore.js +137 -0
- package/dist/esm/PartitionedSemaphore.js.map +1 -0
- package/dist/esm/Pretty.js +4 -3
- package/dist/esm/Pretty.js.map +1 -1
- package/dist/esm/Schema.js +15 -14
- package/dist/esm/Schema.js.map +1 -1
- package/dist/esm/SchemaAST.js +4 -3
- package/dist/esm/SchemaAST.js.map +1 -1
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/config.js +10 -9
- package/dist/esm/internal/config.js.map +1 -1
- package/dist/esm/internal/schema/errors.js +6 -5
- package/dist/esm/internal/schema/errors.js.map +1 -1
- package/dist/esm/internal/schema/util.js +2 -72
- package/dist/esm/internal/schema/util.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/package.json +9 -1
- package/src/Inspectable.ts +115 -2
- package/src/ParseResult.ts +1 -1
- package/src/PartitionedSemaphore.ts +200 -0
- package/src/Pretty.ts +4 -3
- package/src/Schema.ts +18 -14
- package/src/SchemaAST.ts +4 -3
- package/src/Types.ts +1 -1
- package/src/index.ts +6 -0
- package/src/internal/config.ts +15 -9
- package/src/internal/schema/errors.ts +12 -5
- package/src/internal/schema/util.ts +2 -100
- package/src/internal/version.ts +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as array_ from "../../Array.js";
|
|
2
|
+
import * as Inspectable from "../../Inspectable.js";
|
|
2
3
|
import * as util_ from "./util.js";
|
|
3
4
|
const getErrorMessage = (reason, details, path, ast) => {
|
|
4
5
|
let out = reason;
|
|
@@ -44,7 +45,7 @@ export const getJSONSchemaMissingIdentifierAnnotationErrorMessage = (path, ast)
|
|
|
44
45
|
/** @internal */
|
|
45
46
|
export const getJSONSchemaUnsupportedPostRestElementsErrorMessage = path => getErrorMessage("Generating a JSON Schema for post-rest elements is not currently supported. You're welcome to contribute by submitting a Pull Request", undefined, path);
|
|
46
47
|
/** @internal */
|
|
47
|
-
export const getJSONSchemaUnsupportedKeyErrorMessage = (key, path) => getErrorMessage("Unsupported key", `Cannot encode ${
|
|
48
|
+
export const getJSONSchemaUnsupportedKeyErrorMessage = (key, path) => getErrorMessage("Unsupported key", `Cannot encode ${Inspectable.formatPropertyKey(key)} key to JSON Schema`, path);
|
|
48
49
|
// ---------------------------------------------
|
|
49
50
|
// Pretty
|
|
50
51
|
// ---------------------------------------------
|
|
@@ -53,7 +54,7 @@ export const getPrettyMissingAnnotationErrorMessage = (path, ast) => getMissingA
|
|
|
53
54
|
/** @internal */
|
|
54
55
|
export const getPrettyNeverErrorMessage = "Cannot pretty print a `never` value";
|
|
55
56
|
/** @internal */
|
|
56
|
-
export const getPrettyNoMatchingSchemaErrorMessage = (actual, path, ast) => getErrorMessage("Unexpected Error", `Cannot find a matching schema for ${
|
|
57
|
+
export const getPrettyNoMatchingSchemaErrorMessage = (actual, path, ast) => getErrorMessage("Unexpected Error", `Cannot find a matching schema for ${Inspectable.formatUnknown(actual)}`, path, ast);
|
|
57
58
|
// ---------------------------------------------
|
|
58
59
|
// Schema
|
|
59
60
|
// ---------------------------------------------
|
|
@@ -69,7 +70,7 @@ export const getASTUnsupportedSchemaErrorMessage = ast => getUnsupportedSchemaEr
|
|
|
69
70
|
/** @internal */
|
|
70
71
|
export const getASTUnsupportedKeySchemaErrorMessage = ast => getErrorMessage("Unsupported key schema", undefined, undefined, ast);
|
|
71
72
|
/** @internal */
|
|
72
|
-
export const getASTUnsupportedLiteralErrorMessage = literal => getErrorMessage("Unsupported literal", `literal value: ${
|
|
73
|
+
export const getASTUnsupportedLiteralErrorMessage = literal => getErrorMessage("Unsupported literal", `literal value: ${Inspectable.formatUnknown(literal)}`);
|
|
73
74
|
/** @internal */
|
|
74
75
|
export const getASTDuplicateIndexSignatureErrorMessage = type => getErrorMessage("Duplicate index signature", `${type} index signature`);
|
|
75
76
|
/** @internal */
|
|
@@ -77,9 +78,9 @@ export const getASTIndexSignatureParameterErrorMessage = /*#__PURE__*/getErrorMe
|
|
|
77
78
|
/** @internal */
|
|
78
79
|
export const getASTRequiredElementFollowinAnOptionalElementErrorMessage = /*#__PURE__*/getErrorMessage("Invalid element", "A required element cannot follow an optional element. ts(1257)");
|
|
79
80
|
/** @internal */
|
|
80
|
-
export const getASTDuplicatePropertySignatureTransformationErrorMessage = key => getErrorMessage("Duplicate property signature transformation", `Duplicate key ${
|
|
81
|
+
export const getASTDuplicatePropertySignatureTransformationErrorMessage = key => getErrorMessage("Duplicate property signature transformation", `Duplicate key ${Inspectable.formatUnknown(key)}`);
|
|
81
82
|
/** @internal */
|
|
82
83
|
export const getASTUnsupportedRenameSchemaErrorMessage = ast => getUnsupportedSchemaErrorMessage(undefined, undefined, ast);
|
|
83
84
|
/** @internal */
|
|
84
|
-
export const getASTDuplicatePropertySignatureErrorMessage = key => getErrorMessage("Duplicate property signature", `Duplicate key ${
|
|
85
|
+
export const getASTDuplicatePropertySignatureErrorMessage = key => getErrorMessage("Duplicate property signature", `Duplicate key ${Inspectable.formatUnknown(key)}`);
|
|
85
86
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","names":["array_","util_","getErrorMessage","reason","details","path","ast","out","isNonEmptyReadonlyArray","formatPath","undefined","_tag","getInvalidArgumentErrorMessage","getUnsupportedSchemaErrorMessage","getMissingAnnotationErrorMessage","getArbitraryUnsupportedErrorMessage","getArbitraryMissingAnnotationErrorMessage","getArbitraryEmptyEnumErrorMessage","getEquivalenceUnsupportedErrorMessage","getJSONSchemaMissingAnnotationErrorMessage","getJSONSchemaMissingIdentifierAnnotationErrorMessage","getJSONSchemaUnsupportedPostRestElementsErrorMessage","getJSONSchemaUnsupportedKeyErrorMessage","key","formatPropertyKey","getPrettyMissingAnnotationErrorMessage","getPrettyNeverErrorMessage","getPrettyNoMatchingSchemaErrorMessage","actual","formatUnknown","getSchemaExtendErrorMessage","x","y","getSchemaUnsupportedLiteralSpanErrorMessage","getASTUnsupportedSchemaErrorMessage","getASTUnsupportedKeySchemaErrorMessage","getASTUnsupportedLiteralErrorMessage","literal","getASTDuplicateIndexSignatureErrorMessage","type","getASTIndexSignatureParameterErrorMessage","getASTRequiredElementFollowinAnOptionalElementErrorMessage","getASTDuplicatePropertySignatureTransformationErrorMessage","getASTUnsupportedRenameSchemaErrorMessage","getASTDuplicatePropertySignatureErrorMessage"],"sources":["../../../../src/internal/schema/errors.ts"],"sourcesContent":[null],"mappings":"AAAA,OAAO,KAAKA,MAAM,MAAM,gBAAgB;
|
|
1
|
+
{"version":3,"file":"errors.js","names":["array_","Inspectable","util_","getErrorMessage","reason","details","path","ast","out","isNonEmptyReadonlyArray","formatPath","undefined","_tag","getInvalidArgumentErrorMessage","getUnsupportedSchemaErrorMessage","getMissingAnnotationErrorMessage","getArbitraryUnsupportedErrorMessage","getArbitraryMissingAnnotationErrorMessage","getArbitraryEmptyEnumErrorMessage","getEquivalenceUnsupportedErrorMessage","getJSONSchemaMissingAnnotationErrorMessage","getJSONSchemaMissingIdentifierAnnotationErrorMessage","getJSONSchemaUnsupportedPostRestElementsErrorMessage","getJSONSchemaUnsupportedKeyErrorMessage","key","formatPropertyKey","getPrettyMissingAnnotationErrorMessage","getPrettyNeverErrorMessage","getPrettyNoMatchingSchemaErrorMessage","actual","formatUnknown","getSchemaExtendErrorMessage","x","y","getSchemaUnsupportedLiteralSpanErrorMessage","getASTUnsupportedSchemaErrorMessage","getASTUnsupportedKeySchemaErrorMessage","getASTUnsupportedLiteralErrorMessage","literal","getASTDuplicateIndexSignatureErrorMessage","type","getASTIndexSignatureParameterErrorMessage","getASTRequiredElementFollowinAnOptionalElementErrorMessage","getASTDuplicatePropertySignatureTransformationErrorMessage","getASTUnsupportedRenameSchemaErrorMessage","getASTDuplicatePropertySignatureErrorMessage"],"sources":["../../../../src/internal/schema/errors.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as Inspectable from "../../Inspectable.js";
|
|
2
2
|
/** @internal */
|
|
3
3
|
export const getKeysForIndexSignature = (input, parameter) => {
|
|
4
4
|
switch (parameter._tag) {
|
|
@@ -25,81 +25,11 @@ export const memoizeThunk = f => {
|
|
|
25
25
|
};
|
|
26
26
|
};
|
|
27
27
|
/** @internal */
|
|
28
|
-
export const formatDate = date => {
|
|
29
|
-
try {
|
|
30
|
-
return date.toISOString();
|
|
31
|
-
} catch {
|
|
32
|
-
return String(date);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
const CIRCULAR = "[Circular]";
|
|
36
|
-
/** @internal */
|
|
37
|
-
export function formatUnknown(input, whitespace = 0) {
|
|
38
|
-
const seen = new WeakSet();
|
|
39
|
-
const gap = !whitespace ? "" : typeof whitespace === "number" ? " ".repeat(whitespace) : whitespace;
|
|
40
|
-
const ind = d => gap.repeat(d);
|
|
41
|
-
const safeToString = x => {
|
|
42
|
-
try {
|
|
43
|
-
const s = x.toString();
|
|
44
|
-
return typeof s === "string" ? s : String(s);
|
|
45
|
-
} catch {
|
|
46
|
-
return "[toString threw]";
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
const wrap = (v, body) => {
|
|
50
|
-
const ctor = v?.constructor;
|
|
51
|
-
return ctor && ctor !== Object.prototype.constructor && ctor.name ? `${ctor.name}(${body})` : body;
|
|
52
|
-
};
|
|
53
|
-
const ownKeys = o => {
|
|
54
|
-
try {
|
|
55
|
-
return Reflect.ownKeys(o);
|
|
56
|
-
} catch {
|
|
57
|
-
return ["[ownKeys threw]"];
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
function go(v, d = 0) {
|
|
61
|
-
if (Array.isArray(v)) {
|
|
62
|
-
if (seen.has(v)) return CIRCULAR;
|
|
63
|
-
seen.add(v);
|
|
64
|
-
if (!gap || v.length <= 1) return `[${v.map(x => go(x, d)).join(",")}]`;
|
|
65
|
-
const inner = v.map(x => go(x, d + 1)).join(",\n" + ind(d + 1));
|
|
66
|
-
return `[\n${ind(d + 1)}${inner}\n${ind(d)}]`;
|
|
67
|
-
}
|
|
68
|
-
if (Predicate.isDate(v)) return formatDate(v);
|
|
69
|
-
if (Predicate.hasProperty(v, "toString") && Predicate.isFunction(v["toString"]) && v["toString"] !== Object.prototype.toString) return safeToString(v);
|
|
70
|
-
if (Predicate.isString(v)) return JSON.stringify(v);
|
|
71
|
-
if (Predicate.isNumber(v) || v == null || Predicate.isBoolean(v) || Predicate.isSymbol(v)) return String(v);
|
|
72
|
-
if (Predicate.isBigInt(v)) return String(v) + "n";
|
|
73
|
-
if (v instanceof Set || v instanceof Map) {
|
|
74
|
-
if (seen.has(v)) return CIRCULAR;
|
|
75
|
-
seen.add(v);
|
|
76
|
-
return `${v.constructor.name}(${go(Array.from(v), d)})`;
|
|
77
|
-
}
|
|
78
|
-
if (Predicate.isObject(v)) {
|
|
79
|
-
if (seen.has(v)) return CIRCULAR;
|
|
80
|
-
seen.add(v);
|
|
81
|
-
const keys = ownKeys(v);
|
|
82
|
-
if (!gap || keys.length <= 1) {
|
|
83
|
-
const body = `{${keys.map(k => `${formatPropertyKey(k)}:${go(v[k], d)}`).join(",")}}`;
|
|
84
|
-
return wrap(v, body);
|
|
85
|
-
}
|
|
86
|
-
const body = `{\n${keys.map(k => `${ind(d + 1)}${formatPropertyKey(k)}: ${go(v[k], d + 1)}`).join(",\n")}\n${ind(d)}}`;
|
|
87
|
-
return wrap(v, body);
|
|
88
|
-
}
|
|
89
|
-
return String(v);
|
|
90
|
-
}
|
|
91
|
-
return go(input, 0);
|
|
92
|
-
}
|
|
93
|
-
/** @internal */
|
|
94
|
-
export function formatPropertyKey(name) {
|
|
95
|
-
return Predicate.isString(name) ? JSON.stringify(name) : String(name);
|
|
96
|
-
}
|
|
97
|
-
/** @internal */
|
|
98
28
|
export const isNonEmpty = x => Array.isArray(x);
|
|
99
29
|
/** @internal */
|
|
100
30
|
export const isSingle = x => !Array.isArray(x);
|
|
101
31
|
/** @internal */
|
|
102
|
-
export const formatPathKey = key => `[${formatPropertyKey(key)}]`;
|
|
32
|
+
export const formatPathKey = key => `[${Inspectable.formatPropertyKey(key)}]`;
|
|
103
33
|
/** @internal */
|
|
104
34
|
export const formatPath = path => isNonEmpty(path) ? path.map(formatPathKey).join("") : formatPathKey(path);
|
|
105
35
|
//# sourceMappingURL=util.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","names":["
|
|
1
|
+
{"version":3,"file":"util.js","names":["Inspectable","getKeysForIndexSignature","input","parameter","_tag","Object","keys","getOwnPropertySymbols","from","memoizeThunk","f","done","a","isNonEmpty","x","Array","isArray","isSingle","formatPathKey","key","formatPropertyKey","formatPath","path","map","join"],"sources":["../../../../src/internal/schema/util.ts"],"sourcesContent":[null],"mappings":"AACA,OAAO,KAAKA,WAAW,MAAM,sBAAsB;AAInD;AACA,OAAO,MAAMC,wBAAwB,GAAGA,CACtCC,KAA6C,EAC7CC,SAAwB,KACyB;EACjD,QAAQA,SAAS,CAACC,IAAI;IACpB,KAAK,eAAe;IACpB,KAAK,iBAAiB;MACpB,OAAOC,MAAM,CAACC,IAAI,CAACJ,KAAK,CAAC;IAC3B,KAAK,eAAe;MAClB,OAAOG,MAAM,CAACE,qBAAqB,CAACL,KAAK,CAAC;IAC5C,KAAK,YAAY;MACf,OAAOD,wBAAwB,CAACC,KAAK,EAAEC,SAAS,CAACK,IAAI,CAAC;EAC1D;AACF,CAAC;AAED;AACA,OAAO,MAAMC,YAAY,GAAOC,CAAU,IAAa;EACrD,IAAIC,IAAI,GAAG,KAAK;EAChB,IAAIC,CAAI;EACR,OAAO,MAAK;IACV,IAAID,IAAI,EAAE;MACR,OAAOC,CAAC;IACV;IACAA,CAAC,GAAGF,CAAC,EAAE;IACPC,IAAI,GAAG,IAAI;IACX,OAAOC,CAAC;EACV,CAAC;AACH,CAAC;AAKD;AACA,OAAO,MAAMC,UAAU,GAAOC,CAAkC,IAAoCC,KAAK,CAACC,OAAO,CAACF,CAAC,CAAC;AAEpH;AACA,OAAO,MAAMG,QAAQ,GAAOH,CAAuB,IAAa,CAACC,KAAK,CAACC,OAAO,CAACF,CAAC,CAAC;AAEjF;AACA,OAAO,MAAMI,aAAa,GAAIC,GAAgB,IAAa,IAAInB,WAAW,CAACoB,iBAAiB,CAACD,GAAG,CAAC,GAAG;AAEpG;AACA,OAAO,MAAME,UAAU,GAAIC,IAAsB,IAC/CT,UAAU,CAACS,IAAI,CAAC,GAAGA,IAAI,CAACC,GAAG,CAACL,aAAa,CAAC,CAACM,IAAI,CAAC,EAAE,CAAC,GAAGN,aAAa,CAACI,IAAI,CAAC","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "effect",
|
|
3
|
-
"version": "3.19.
|
|
3
|
+
"version": "3.19.4",
|
|
4
4
|
"description": "The missing standard library for TypeScript, for writing production-grade software.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -492,6 +492,11 @@
|
|
|
492
492
|
"import": "./dist/esm/ParseResult.js",
|
|
493
493
|
"default": "./dist/cjs/ParseResult.js"
|
|
494
494
|
},
|
|
495
|
+
"./PartitionedSemaphore": {
|
|
496
|
+
"types": "./dist/dts/PartitionedSemaphore.d.ts",
|
|
497
|
+
"import": "./dist/esm/PartitionedSemaphore.js",
|
|
498
|
+
"default": "./dist/cjs/PartitionedSemaphore.js"
|
|
499
|
+
},
|
|
495
500
|
"./Pipeable": {
|
|
496
501
|
"types": "./dist/dts/Pipeable.d.ts",
|
|
497
502
|
"import": "./dist/esm/Pipeable.js",
|
|
@@ -1189,6 +1194,9 @@
|
|
|
1189
1194
|
"ParseResult": [
|
|
1190
1195
|
"./dist/dts/ParseResult.d.ts"
|
|
1191
1196
|
],
|
|
1197
|
+
"PartitionedSemaphore": [
|
|
1198
|
+
"./dist/dts/PartitionedSemaphore.d.ts"
|
|
1199
|
+
],
|
|
1192
1200
|
"Pipeable": [
|
|
1193
1201
|
"./dist/dts/Pipeable.d.ts"
|
|
1194
1202
|
],
|
package/src/Inspectable.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type * as FiberRefs from "./FiberRefs.js"
|
|
5
5
|
import { globalValue } from "./GlobalValue.js"
|
|
6
|
-
import
|
|
6
|
+
import * as Predicate from "./Predicate.js"
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @since 2.0.0
|
|
@@ -33,7 +33,7 @@ export interface Inspectable {
|
|
|
33
33
|
export const toJSON = (x: unknown): unknown => {
|
|
34
34
|
try {
|
|
35
35
|
if (
|
|
36
|
-
hasProperty(x, "toJSON") && isFunction(x["toJSON"]) &&
|
|
36
|
+
Predicate.hasProperty(x, "toJSON") && Predicate.isFunction(x["toJSON"]) &&
|
|
37
37
|
x["toJSON"].length === 0
|
|
38
38
|
) {
|
|
39
39
|
return x.toJSON()
|
|
@@ -46,6 +46,119 @@ export const toJSON = (x: unknown): unknown => {
|
|
|
46
46
|
return redact(x)
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
const CIRCULAR = "[Circular]"
|
|
50
|
+
|
|
51
|
+
/** @internal */
|
|
52
|
+
export function formatDate(date: Date): string {
|
|
53
|
+
try {
|
|
54
|
+
return date.toISOString()
|
|
55
|
+
} catch {
|
|
56
|
+
return "Invalid Date"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function safeToString(input: any): string {
|
|
61
|
+
try {
|
|
62
|
+
const s = input.toString()
|
|
63
|
+
return typeof s === "string" ? s : String(s)
|
|
64
|
+
} catch {
|
|
65
|
+
return "[toString threw]"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** @internal */
|
|
70
|
+
export function formatPropertyKey(name: PropertyKey): string {
|
|
71
|
+
return Predicate.isString(name) ? JSON.stringify(name) : String(name)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** @internal */
|
|
75
|
+
export function formatUnknown(
|
|
76
|
+
input: unknown,
|
|
77
|
+
options?: {
|
|
78
|
+
readonly space?: number | string | undefined
|
|
79
|
+
readonly ignoreToString?: boolean | undefined
|
|
80
|
+
}
|
|
81
|
+
): string {
|
|
82
|
+
const space = options?.space ?? 0
|
|
83
|
+
const seen = new WeakSet<object>()
|
|
84
|
+
const gap = !space ? "" : (Predicate.isNumber(space) ? " ".repeat(space) : space)
|
|
85
|
+
const ind = (d: number) => gap.repeat(d)
|
|
86
|
+
|
|
87
|
+
const wrap = (v: unknown, body: string): string => {
|
|
88
|
+
const ctor = (v as any)?.constructor
|
|
89
|
+
return ctor && ctor !== Object.prototype.constructor && ctor.name ? `${ctor.name}(${body})` : body
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const ownKeys = (o: object): Array<PropertyKey> => {
|
|
93
|
+
try {
|
|
94
|
+
return Reflect.ownKeys(o)
|
|
95
|
+
} catch {
|
|
96
|
+
return ["[ownKeys threw]"]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function go(v: unknown, d = 0): string {
|
|
101
|
+
if (Array.isArray(v)) {
|
|
102
|
+
if (seen.has(v)) return CIRCULAR
|
|
103
|
+
seen.add(v)
|
|
104
|
+
if (!gap || v.length <= 1) return `[${v.map((x) => go(x, d)).join(",")}]`
|
|
105
|
+
const inner = v.map((x) => go(x, d + 1)).join(",\n" + ind(d + 1))
|
|
106
|
+
return `[\n${ind(d + 1)}${inner}\n${ind(d)}]`
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (Predicate.isDate(v)) return formatDate(v)
|
|
110
|
+
|
|
111
|
+
if (
|
|
112
|
+
!options?.ignoreToString &&
|
|
113
|
+
Predicate.hasProperty(v, "toString") &&
|
|
114
|
+
Predicate.isFunction(v["toString"]) &&
|
|
115
|
+
v["toString"] !== Object.prototype.toString &&
|
|
116
|
+
v["toString"] !== Array.prototype.toString
|
|
117
|
+
) {
|
|
118
|
+
const s = safeToString(v)
|
|
119
|
+
if (v instanceof Error && v.cause) {
|
|
120
|
+
return `${s} (cause: ${go(v.cause, d)})`
|
|
121
|
+
}
|
|
122
|
+
return s
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (Predicate.isString(v)) return JSON.stringify(v)
|
|
126
|
+
|
|
127
|
+
if (
|
|
128
|
+
Predicate.isNumber(v) ||
|
|
129
|
+
v == null ||
|
|
130
|
+
Predicate.isBoolean(v) ||
|
|
131
|
+
Predicate.isSymbol(v)
|
|
132
|
+
) return String(v)
|
|
133
|
+
|
|
134
|
+
if (Predicate.isBigInt(v)) return String(v) + "n"
|
|
135
|
+
|
|
136
|
+
if (v instanceof Set || v instanceof Map) {
|
|
137
|
+
if (seen.has(v)) return CIRCULAR
|
|
138
|
+
seen.add(v)
|
|
139
|
+
return `${v.constructor.name}(${go(Array.from(v), d)})`
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (Predicate.isObject(v)) {
|
|
143
|
+
if (seen.has(v)) return CIRCULAR
|
|
144
|
+
seen.add(v)
|
|
145
|
+
const keys = ownKeys(v)
|
|
146
|
+
if (!gap || keys.length <= 1) {
|
|
147
|
+
const body = `{${keys.map((k) => `${formatPropertyKey(k)}:${go((v as any)[k], d)}`).join(",")}}`
|
|
148
|
+
return wrap(v, body)
|
|
149
|
+
}
|
|
150
|
+
const body = `{\n${
|
|
151
|
+
keys.map((k) => `${ind(d + 1)}${formatPropertyKey(k)}: ${go((v as any)[k], d + 1)}`).join(",\n")
|
|
152
|
+
}\n${ind(d)}}`
|
|
153
|
+
return wrap(v, body)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return String(v)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return go(input, 0)
|
|
160
|
+
}
|
|
161
|
+
|
|
49
162
|
/**
|
|
50
163
|
* @since 2.0.0
|
|
51
164
|
*/
|
package/src/ParseResult.ts
CHANGED
|
@@ -1911,7 +1911,7 @@ function getDefaultTypeMessage(issue: Type): string {
|
|
|
1911
1911
|
return issue.message
|
|
1912
1912
|
}
|
|
1913
1913
|
const expected = AST.isRefinement(issue.ast) ? getRefinementExpected(issue.ast) : String(issue.ast)
|
|
1914
|
-
return `Expected ${expected}, actual ${
|
|
1914
|
+
return `Expected ${expected}, actual ${Inspectable.formatUnknown(issue.actual)}`
|
|
1915
1915
|
}
|
|
1916
1916
|
|
|
1917
1917
|
const formatTypeMessage = (issue: Type): Effect.Effect<string> =>
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 3.19.4
|
|
3
|
+
* @experimental
|
|
4
|
+
*/
|
|
5
|
+
import * as Effect from "./Effect.js"
|
|
6
|
+
import * as Iterable from "./Iterable.js"
|
|
7
|
+
import * as MutableHashMap from "./MutableHashMap.js"
|
|
8
|
+
import * as Option from "./Option.js"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @since 3.19.4
|
|
12
|
+
* @category Models
|
|
13
|
+
* @experimental
|
|
14
|
+
*/
|
|
15
|
+
export const TypeId: TypeId = "~effect/PartitionedSemaphore"
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @since 3.19.4
|
|
19
|
+
* @category Models
|
|
20
|
+
* @experimental
|
|
21
|
+
*/
|
|
22
|
+
export type TypeId = "~effect/PartitionedSemaphore"
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A `PartitionedSemaphore` is a concurrency primitive that can be used to
|
|
26
|
+
* control concurrent access to a resource across multiple partitions identified
|
|
27
|
+
* by keys.
|
|
28
|
+
*
|
|
29
|
+
* The total number of permits is shared across all partitions, with waiting
|
|
30
|
+
* permits equally distributed among partitions using a round-robin strategy.
|
|
31
|
+
*
|
|
32
|
+
* This is useful when you want to limit the total number of concurrent accesses
|
|
33
|
+
* to a resource, while still allowing for fair distribution of access across
|
|
34
|
+
* different partitions.
|
|
35
|
+
*
|
|
36
|
+
* @since 3.19.4
|
|
37
|
+
* @category Models
|
|
38
|
+
* @experimental
|
|
39
|
+
*/
|
|
40
|
+
export interface PartitionedSemaphore<in K> {
|
|
41
|
+
readonly [TypeId]: TypeId
|
|
42
|
+
|
|
43
|
+
readonly withPermits: (
|
|
44
|
+
key: K,
|
|
45
|
+
permits: number
|
|
46
|
+
) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* A `PartitionedSemaphore` is a concurrency primitive that can be used to
|
|
51
|
+
* control concurrent access to a resource across multiple partitions identified
|
|
52
|
+
* by keys.
|
|
53
|
+
*
|
|
54
|
+
* The total number of permits is shared across all partitions, with waiting
|
|
55
|
+
* permits equally distributed among partitions using a round-robin strategy.
|
|
56
|
+
*
|
|
57
|
+
* This is useful when you want to limit the total number of concurrent accesses
|
|
58
|
+
* to a resource, while still allowing for fair distribution of access across
|
|
59
|
+
* different partitions.
|
|
60
|
+
*
|
|
61
|
+
* @since 3.19.4
|
|
62
|
+
* @category Constructors
|
|
63
|
+
* @experimental
|
|
64
|
+
*/
|
|
65
|
+
export const makeUnsafe = <K = unknown>(options: {
|
|
66
|
+
readonly permits: number
|
|
67
|
+
}): PartitionedSemaphore<K> => {
|
|
68
|
+
const maxPermits = Math.max(0, options.permits)
|
|
69
|
+
|
|
70
|
+
if (!Number.isFinite(maxPermits)) {
|
|
71
|
+
return {
|
|
72
|
+
[TypeId]: TypeId,
|
|
73
|
+
withPermits: () => (effect) => effect
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let totalPermits = maxPermits
|
|
78
|
+
let waitingPermits = 0
|
|
79
|
+
|
|
80
|
+
type Waiter = {
|
|
81
|
+
permits: number
|
|
82
|
+
readonly resume: () => void
|
|
83
|
+
}
|
|
84
|
+
const partitions = MutableHashMap.empty<K, Set<Waiter>>()
|
|
85
|
+
|
|
86
|
+
const take = (key: K, permits: number) =>
|
|
87
|
+
Effect.async<void>((resume) => {
|
|
88
|
+
if (maxPermits < permits) {
|
|
89
|
+
return resume(Effect.never)
|
|
90
|
+
} else if (totalPermits >= permits) {
|
|
91
|
+
totalPermits -= permits
|
|
92
|
+
return resume(Effect.void)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const needed = permits - totalPermits
|
|
96
|
+
const taken = permits - needed
|
|
97
|
+
if (totalPermits > 0) {
|
|
98
|
+
totalPermits = 0
|
|
99
|
+
}
|
|
100
|
+
waitingPermits += needed
|
|
101
|
+
|
|
102
|
+
const waiters = Option.getOrElse(
|
|
103
|
+
MutableHashMap.get(partitions, key),
|
|
104
|
+
() => {
|
|
105
|
+
const set = new Set<Waiter>()
|
|
106
|
+
MutableHashMap.set(partitions, key, set)
|
|
107
|
+
return set
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
const entry: Waiter = {
|
|
112
|
+
permits: needed,
|
|
113
|
+
resume() {
|
|
114
|
+
cleanup()
|
|
115
|
+
resume(Effect.void)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function cleanup() {
|
|
119
|
+
waiters.delete(entry)
|
|
120
|
+
if (waiters.size === 0) {
|
|
121
|
+
MutableHashMap.remove(partitions, key)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
waiters.add(entry)
|
|
125
|
+
return Effect.sync(() => {
|
|
126
|
+
cleanup()
|
|
127
|
+
waitingPermits -= entry.permits
|
|
128
|
+
if (taken > 0) {
|
|
129
|
+
releaseUnsafe(taken)
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
let iterator = partitions[Symbol.iterator]()
|
|
135
|
+
const releaseUnsafe = (permits: number) => {
|
|
136
|
+
while (permits > 0) {
|
|
137
|
+
if (waitingPermits === 0) {
|
|
138
|
+
totalPermits += permits
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let state = iterator.next()
|
|
143
|
+
if (state.done) {
|
|
144
|
+
iterator = partitions[Symbol.iterator]()
|
|
145
|
+
state = iterator.next()
|
|
146
|
+
if (state.done) return
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const entry = Iterable.unsafeHead(state.value[1])
|
|
150
|
+
entry.permits--
|
|
151
|
+
waitingPermits--
|
|
152
|
+
if (entry.permits === 0) entry.resume()
|
|
153
|
+
permits--
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
[TypeId]: TypeId,
|
|
159
|
+
withPermits: (key, permits) => {
|
|
160
|
+
const takePermits = take(key, permits)
|
|
161
|
+
const release: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> = Effect.matchCauseEffect({
|
|
162
|
+
onFailure(cause) {
|
|
163
|
+
releaseUnsafe(permits)
|
|
164
|
+
return Effect.failCause(cause)
|
|
165
|
+
},
|
|
166
|
+
onSuccess(value) {
|
|
167
|
+
releaseUnsafe(permits)
|
|
168
|
+
return Effect.succeed(value)
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
return (effect) =>
|
|
172
|
+
Effect.uninterruptibleMask((restore) =>
|
|
173
|
+
Effect.flatMap(
|
|
174
|
+
restore(takePermits),
|
|
175
|
+
() => release(restore(effect))
|
|
176
|
+
)
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* A `PartitionedSemaphore` is a concurrency primitive that can be used to
|
|
184
|
+
* control concurrent access to a resource across multiple partitions identified
|
|
185
|
+
* by keys.
|
|
186
|
+
*
|
|
187
|
+
* The total number of permits is shared across all partitions, with waiting
|
|
188
|
+
* permits equally distributed among partitions using a round-robin strategy.
|
|
189
|
+
*
|
|
190
|
+
* This is useful when you want to limit the total number of concurrent accesses
|
|
191
|
+
* to a resource, while still allowing for fair distribution of access across
|
|
192
|
+
* different partitions.
|
|
193
|
+
*
|
|
194
|
+
* @since 3.19.4
|
|
195
|
+
* @category Constructors
|
|
196
|
+
* @experimental
|
|
197
|
+
*/
|
|
198
|
+
export const make = <K = unknown>(options: {
|
|
199
|
+
readonly permits: number
|
|
200
|
+
}): Effect.Effect<PartitionedSemaphore<K>> => Effect.sync(() => makeUnsafe<K>(options))
|
package/src/Pretty.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @since 3.10.0
|
|
3
3
|
*/
|
|
4
4
|
import * as Arr from "./Array.js"
|
|
5
|
+
import * as Inspectable from "./Inspectable.js"
|
|
5
6
|
import * as errors_ from "./internal/schema/errors.js"
|
|
6
7
|
import * as util_ from "./internal/schema/util.js"
|
|
7
8
|
import * as Option from "./Option.js"
|
|
@@ -43,7 +44,7 @@ const toString = getMatcher((a) => String(a))
|
|
|
43
44
|
|
|
44
45
|
const stringify = getMatcher((a) => JSON.stringify(a))
|
|
45
46
|
|
|
46
|
-
const formatUnknown = getMatcher(
|
|
47
|
+
const formatUnknown = getMatcher(Inspectable.formatUnknown)
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* @since 3.10.0
|
|
@@ -142,7 +143,7 @@ export const match: AST.Match<Pretty<any>> = {
|
|
|
142
143
|
continue
|
|
143
144
|
}
|
|
144
145
|
output.push(
|
|
145
|
-
`${
|
|
146
|
+
`${Inspectable.formatPropertyKey(name)}: ${propertySignaturesTypes[i](input[name])}`
|
|
146
147
|
)
|
|
147
148
|
}
|
|
148
149
|
// ---------------------------------------------
|
|
@@ -156,7 +157,7 @@ export const match: AST.Match<Pretty<any>> = {
|
|
|
156
157
|
if (Object.prototype.hasOwnProperty.call(expectedKeys, key)) {
|
|
157
158
|
continue
|
|
158
159
|
}
|
|
159
|
-
output.push(`${
|
|
160
|
+
output.push(`${Inspectable.formatPropertyKey(key)}: ${type(input[key])}`)
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
163
|
}
|