effect 4.0.4 → 4.0.5
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/ai-docs/src/52_graphql/10_basics.ts +19 -13
- package/ai-docs/src/52_graphql/30_batching.ts +6 -4
- package/ai-docs/src/52_graphql/40_aliased-batching.ts +6 -4
- package/dist/Array.d.ts +90 -6
- package/dist/Array.d.ts.map +1 -1
- package/dist/Array.js +4 -2
- package/dist/Array.js.map +1 -1
- package/dist/Channel.d.ts +6 -1
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +17 -3
- package/dist/Channel.js.map +1 -1
- package/dist/ConfigProvider.d.ts.map +1 -1
- package/dist/ConfigProvider.js +33 -32
- package/dist/ConfigProvider.js.map +1 -1
- package/dist/Duration.d.ts.map +1 -1
- package/dist/Duration.js +2 -5
- package/dist/Duration.js.map +1 -1
- package/dist/Effect.d.ts +61 -19
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +58 -39
- package/dist/Effect.js.map +1 -1
- package/dist/FileSystem.d.ts +23 -9
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js.map +1 -1
- package/dist/Match.d.ts +20 -6
- package/dist/Match.d.ts.map +1 -1
- package/dist/Match.js +2 -2
- package/dist/Match.js.map +1 -1
- package/dist/Path.d.ts +37 -5
- package/dist/Path.d.ts.map +1 -1
- package/dist/Path.js +36 -5
- package/dist/Path.js.map +1 -1
- package/dist/Schema.d.ts +7 -2
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +9 -2
- package/dist/Schema.js.map +1 -1
- package/dist/String.d.ts +12 -0
- package/dist/String.d.ts.map +1 -1
- package/dist/String.js +17 -4
- package/dist/String.js.map +1 -1
- package/dist/TxRef.d.ts.map +1 -1
- package/dist/TxRef.js +3 -2
- package/dist/TxRef.js.map +1 -1
- package/dist/ai/AiError.d.ts +10 -10
- package/dist/ai/AiError.d.ts.map +1 -1
- package/dist/ai/AiError.js +1 -1
- package/dist/ai/AiError.js.map +1 -1
- package/dist/ai/Decision.d.ts +70 -19
- package/dist/ai/Decision.d.ts.map +1 -1
- package/dist/ai/Decision.js +37 -3
- package/dist/ai/Decision.js.map +1 -1
- package/dist/ai/DecisionModel.js +1 -1
- package/dist/ai/DecisionModel.js.map +1 -1
- package/dist/ai/LanguageModel.d.ts.map +1 -1
- package/dist/ai/LanguageModel.js +47 -35
- package/dist/ai/LanguageModel.js.map +1 -1
- package/dist/ai/McpServer.d.ts +6 -52
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +2 -28
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/Response.d.ts +1 -1
- package/dist/cli/Completions.d.ts +5 -0
- package/dist/cli/Completions.d.ts.map +1 -1
- package/dist/cli/Completions.js.map +1 -1
- package/dist/cli/Flag.d.ts +100 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +33 -0
- package/dist/cli/Flag.js.map +1 -1
- package/dist/cli/Param.d.ts +87 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +30 -0
- package/dist/cli/Param.js.map +1 -1
- package/dist/cli/internal/command.d.ts.map +1 -1
- package/dist/cli/internal/command.js +2 -1
- package/dist/cli/internal/command.js.map +1 -1
- package/dist/cli/internal/completions/bash.js +4 -3
- package/dist/cli/internal/completions/bash.js.map +1 -1
- package/dist/cli/internal/completions/descriptor.js +8 -1
- package/dist/cli/internal/completions/descriptor.js.map +1 -1
- package/dist/cli/internal/completions/fish.js +4 -4
- package/dist/cli/internal/completions/fish.js.map +1 -1
- package/dist/cli/internal/completions/powershell.js +3 -2
- package/dist/cli/internal/completions/powershell.js.map +1 -1
- package/dist/cli/internal/completions/zsh.js +7 -3
- package/dist/cli/internal/completions/zsh.js.map +1 -1
- package/dist/cli/internal/parser.js +11 -3
- package/dist/cli/internal/parser.js.map +1 -1
- package/dist/cli/internal/wizard.d.ts.map +1 -1
- package/dist/cli/internal/wizard.js +2 -1
- package/dist/cli/internal/wizard.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts +1 -0
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +67 -13
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +20 -12
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Runners.d.ts.map +1 -1
- package/dist/cluster/Runners.js +54 -34
- package/dist/cluster/Runners.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +1 -1
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/encoding/Sse.js +1 -1
- package/dist/encoding/Sse.js.map +1 -1
- package/dist/graphql/GraphQLClient.d.ts.map +1 -1
- package/dist/graphql/GraphQLClient.js +12 -5
- package/dist/graphql/GraphQLClient.js.map +1 -1
- package/dist/graphql/GraphQLProtocol.d.ts +249 -11
- package/dist/graphql/GraphQLProtocol.d.ts.map +1 -1
- package/dist/graphql/GraphQLProtocol.js +98 -8
- package/dist/graphql/GraphQLProtocol.js.map +1 -1
- package/dist/graphql/GraphQLResolver.d.ts +1 -1
- package/dist/graphql/GraphQLResolver.d.ts.map +1 -1
- package/dist/graphql/GraphQLResolver.js +46 -16
- package/dist/graphql/GraphQLResolver.js.map +1 -1
- package/dist/http/FetchHttpClient.d.ts +6 -3
- package/dist/http/FetchHttpClient.d.ts.map +1 -1
- package/dist/http/FetchHttpClient.js +6 -3
- package/dist/http/FetchHttpClient.js.map +1 -1
- package/dist/http/FindMyWay/internal/router.js +2 -1
- package/dist/http/FindMyWay/internal/router.js.map +1 -1
- package/dist/http/Headers.d.ts +3 -3
- package/dist/http/Headers.d.ts.map +1 -1
- package/dist/http/Headers.js +6 -5
- package/dist/http/Headers.js.map +1 -1
- package/dist/http/HttpClient.d.ts +12 -0
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +14 -1
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpClientError.d.ts.map +1 -1
- package/dist/http/HttpClientError.js +8 -6
- package/dist/http/HttpClientError.js.map +1 -1
- package/dist/http/HttpClientRequest.d.ts +147 -4
- package/dist/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/http/HttpClientRequest.js +47 -1
- package/dist/http/HttpClientRequest.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts +60 -0
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +67 -5
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpRouter.d.ts.map +1 -1
- package/dist/http/HttpRouter.js +52 -13
- package/dist/http/HttpRouter.js.map +1 -1
- package/dist/http/HttpServerError.d.ts.map +1 -1
- package/dist/http/HttpServerError.js +6 -4
- package/dist/http/HttpServerError.js.map +1 -1
- package/dist/http/HttpServerRequest.js +2 -2
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/http/HttpStaticServer.js +4 -10
- package/dist/http/HttpStaticServer.js.map +1 -1
- package/dist/http/HttpTraceContext.js +1 -1
- package/dist/http/HttpTraceContext.js.map +1 -1
- package/dist/http/Url.d.ts.map +1 -1
- package/dist/http/Url.js +2 -1
- package/dist/http/Url.js.map +1 -1
- package/dist/http/UrlParams.d.ts +112 -8
- package/dist/http/UrlParams.d.ts.map +1 -1
- package/dist/http/UrlParams.js +141 -14
- package/dist/http/UrlParams.js.map +1 -1
- package/dist/http/internal/compression.d.ts +1 -1
- package/dist/http/internal/compression.d.ts.map +1 -1
- package/dist/http/internal/compression.js +2 -10
- package/dist/http/internal/compression.js.map +1 -1
- package/dist/http/internal/compressionBody.d.ts +2 -0
- package/dist/http/internal/compressionBody.d.ts.map +1 -0
- package/dist/http/internal/compressionBody.js +36 -0
- package/dist/http/internal/compressionBody.js.map +1 -0
- package/dist/http/internal/decompression.d.ts +2 -0
- package/dist/http/internal/decompression.d.ts.map +1 -0
- package/dist/http/internal/decompression.js +162 -0
- package/dist/http/internal/decompression.js.map +1 -0
- package/dist/http/internal/tracing.js +14 -4
- package/dist/http/internal/tracing.js.map +1 -1
- package/dist/http/internal/urlParams.d.ts +2 -0
- package/dist/http/internal/urlParams.d.ts.map +1 -0
- package/dist/http/internal/urlParams.js +4 -0
- package/dist/http/internal/urlParams.js.map +1 -0
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +2 -1
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/internal/core.js +17 -1
- package/dist/internal/core.js.map +1 -1
- package/dist/internal/effect.js +5 -3
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/graphql.js +12 -2
- package/dist/internal/graphql.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/observability/Otlp.d.ts +15 -0
- package/dist/observability/Otlp.d.ts.map +1 -1
- package/dist/observability/Otlp.js +3 -0
- package/dist/observability/Otlp.js.map +1 -1
- package/dist/observability/OtlpExporter.d.ts +8 -0
- package/dist/observability/OtlpExporter.d.ts.map +1 -1
- package/dist/observability/OtlpExporter.js +10 -1
- package/dist/observability/OtlpExporter.js.map +1 -1
- package/dist/observability/OtlpLogger.d.ts +17 -0
- package/dist/observability/OtlpLogger.d.ts.map +1 -1
- package/dist/observability/OtlpLogger.js +14 -1
- package/dist/observability/OtlpLogger.js.map +1 -1
- package/dist/observability/OtlpMetrics.d.ts +17 -0
- package/dist/observability/OtlpMetrics.d.ts.map +1 -1
- package/dist/observability/OtlpMetrics.js +13 -0
- package/dist/observability/OtlpMetrics.js.map +1 -1
- package/dist/observability/OtlpTracer.d.ts +17 -0
- package/dist/observability/OtlpTracer.d.ts.map +1 -1
- package/dist/observability/OtlpTracer.js +15 -2
- package/dist/observability/OtlpTracer.js.map +1 -1
- package/dist/reactivity/AsyncResult.d.ts +6 -0
- package/dist/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/reactivity/AsyncResult.js +27 -0
- package/dist/reactivity/AsyncResult.js.map +1 -1
- package/dist/reactivity/AtomRegistry.js +3 -1
- package/dist/reactivity/AtomRegistry.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +6 -1
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/sql/SqlClient.d.ts +8 -7
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +8 -7
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/testing/TestClock.d.ts +16 -3
- package/dist/testing/TestClock.d.ts.map +1 -1
- package/dist/testing/TestClock.js +112 -22
- package/dist/testing/TestClock.js.map +1 -1
- package/dist/workflow/Activity.js +1 -0
- package/dist/workflow/Activity.js.map +1 -1
- package/dist/workflow/Workflow.d.ts +22 -0
- package/dist/workflow/Workflow.d.ts.map +1 -1
- package/dist/workflow/Workflow.js +15 -3
- package/dist/workflow/Workflow.js.map +1 -1
- package/dist/workflow/WorkflowEngine.d.ts +20 -1
- package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
- package/dist/workflow/WorkflowEngine.js +35 -21
- package/dist/workflow/WorkflowEngine.js.map +1 -1
- package/package.json +1 -1
- package/src/Array.ts +95 -6
- package/src/Channel.ts +24 -3
- package/src/ConfigProvider.ts +40 -44
- package/src/Duration.ts +4 -5
- package/src/Effect.ts +140 -53
- package/src/FileSystem.ts +23 -9
- package/src/Match.ts +65 -12
- package/src/Path.ts +52 -7
- package/src/Schema.ts +17 -4
- package/src/String.ts +17 -4
- package/src/TxRef.ts +4 -2
- package/src/ai/AiError.ts +3 -1
- package/src/ai/Decision.ts +70 -21
- package/src/ai/DecisionModel.ts +1 -1
- package/src/ai/LanguageModel.ts +57 -51
- package/src/ai/McpServer.ts +15 -55
- package/src/cli/Completions.ts +5 -0
- package/src/cli/Flag.ts +101 -0
- package/src/cli/Param.ts +96 -0
- package/src/cli/internal/command.ts +2 -1
- package/src/cli/internal/completions/bash.ts +4 -3
- package/src/cli/internal/completions/descriptor.ts +10 -1
- package/src/cli/internal/completions/fish.ts +4 -4
- package/src/cli/internal/completions/powershell.ts +5 -2
- package/src/cli/internal/completions/zsh.ts +7 -3
- package/src/cli/internal/parser.ts +12 -3
- package/src/cli/internal/wizard.ts +2 -1
- package/src/cluster/ClusterWorkflowEngine.ts +92 -24
- package/src/cluster/MessageStorage.ts +14 -3
- package/src/cluster/Runners.ts +88 -66
- package/src/cluster/internal/entityManager.ts +1 -1
- package/src/encoding/Sse.ts +1 -1
- package/src/graphql/GraphQLClient.ts +17 -5
- package/src/graphql/GraphQLProtocol.ts +274 -20
- package/src/graphql/GraphQLResolver.ts +45 -17
- package/src/http/FetchHttpClient.ts +6 -3
- package/src/http/FindMyWay/internal/router.ts +2 -1
- package/src/http/Headers.ts +6 -9
- package/src/http/HttpClient.ts +18 -1
- package/src/http/HttpClientError.ts +10 -6
- package/src/http/HttpClientRequest.ts +173 -7
- package/src/http/HttpMiddleware.ts +85 -5
- package/src/http/HttpRouter.ts +60 -13
- package/src/http/HttpServerError.ts +8 -4
- package/src/http/HttpServerRequest.ts +2 -2
- package/src/http/HttpStaticServer.ts +4 -10
- package/src/http/HttpTraceContext.ts +1 -1
- package/src/http/Url.ts +2 -1
- package/src/http/UrlParams.ts +225 -26
- package/src/http/internal/compression.ts +3 -17
- package/src/http/internal/compressionBody.ts +56 -0
- package/src/http/internal/decompression.ts +226 -0
- package/src/http/internal/tracing.ts +21 -4
- package/src/http/internal/urlParams.ts +5 -0
- package/src/http-api/HttpApiClient.ts +2 -1
- package/src/internal/core.ts +21 -1
- package/src/internal/effect.ts +5 -4
- package/src/internal/graphql.ts +30 -7
- package/src/internal/version.ts +1 -1
- package/src/observability/Otlp.ts +18 -0
- package/src/observability/OtlpExporter.ts +14 -3
- package/src/observability/OtlpLogger.ts +31 -2
- package/src/observability/OtlpMetrics.ts +30 -1
- package/src/observability/OtlpTracer.ts +32 -3
- package/src/reactivity/AsyncResult.ts +31 -0
- package/src/reactivity/AtomRegistry.ts +3 -1
- package/src/rpc/RpcClient.ts +6 -1
- package/src/sql/SqlClient.ts +9 -7
- package/src/testing/TestClock.ts +144 -29
- package/src/workflow/Activity.ts +1 -0
- package/src/workflow/Workflow.ts +31 -5
- package/src/workflow/WorkflowEngine.ts +60 -22
package/src/Match.ts
CHANGED
|
@@ -712,6 +712,26 @@ export const withReturnType: <Ret>() => <I, F, R, A, Pr, _, Args extends Array<a
|
|
|
712
712
|
) => [Ret] extends [[A] extends [never] ? any : A] ? Matcher<I, F, R, A, Pr, Ret, Args>
|
|
713
713
|
: "withReturnType constraint does not extend Result type" = internal.withReturnType
|
|
714
714
|
|
|
715
|
+
// `P` is a const type parameter, so object literals skip excess-property checks.
|
|
716
|
+
// Reject pattern keys that no object variant of the input has. Functions,
|
|
717
|
+
// refinements, and array patterns are not checked.
|
|
718
|
+
type PatternKey<K> = K extends number ? `${K}` : K
|
|
719
|
+
|
|
720
|
+
type PatternKeys<A> = object extends A ? PropertyKey
|
|
721
|
+
: A extends object ? PatternKey<keyof A>
|
|
722
|
+
: never
|
|
723
|
+
|
|
724
|
+
type ObjectPatternGuard<A, P> = [P] extends [Function | ReadonlyArray<any> | SafeRefinement<never, any>] ? unknown
|
|
725
|
+
: [P] extends [object] ? { readonly [K in Exclude<PatternKey<keyof P>, PatternKeys<A>>]: never }
|
|
726
|
+
: unknown
|
|
727
|
+
|
|
728
|
+
type ExactPattern<R, P> = (Types.PatternPrimitive<R> | Types.PatternBase<R>) & ObjectPatternGuard<R, P>
|
|
729
|
+
|
|
730
|
+
type ExactPatterns<R, P> = {
|
|
731
|
+
readonly [I in keyof P]: I extends number | `${number}` ? P[I] & ExactPattern<R, P[I]>
|
|
732
|
+
: P[I]
|
|
733
|
+
}
|
|
734
|
+
|
|
715
735
|
/**
|
|
716
736
|
* Defines a condition for matching values.
|
|
717
737
|
*
|
|
@@ -763,7 +783,7 @@ export const withReturnType: <Ret>() => <I, F, R, A, Pr, _, Args extends Array<a
|
|
|
763
783
|
*/
|
|
764
784
|
export const when: <
|
|
765
785
|
R,
|
|
766
|
-
const P extends
|
|
786
|
+
const P extends ExactPattern<R, P>,
|
|
767
787
|
Ret,
|
|
768
788
|
Args extends Array<any>,
|
|
769
789
|
Fn extends (_: Types.WhenMatch<R, P>, ...args: Args) => Ret
|
|
@@ -831,7 +851,7 @@ export const whenOr: <
|
|
|
831
851
|
Args extends Array<any>,
|
|
832
852
|
Fn extends (_: Types.WhenMatch<R, P[number]>, ...args: Args) => Ret
|
|
833
853
|
>(
|
|
834
|
-
...args: [...patterns:
|
|
854
|
+
...args: [...patterns: ExactPatterns<R, P>, f: Fn]
|
|
835
855
|
) => <I, F, A, Pr>(
|
|
836
856
|
self: Matcher<I, F, R, A, Pr, Ret, Args>
|
|
837
857
|
) => Matcher<
|
|
@@ -842,7 +862,13 @@ export const whenOr: <
|
|
|
842
862
|
Pr,
|
|
843
863
|
Ret,
|
|
844
864
|
Args
|
|
845
|
-
> =
|
|
865
|
+
> = <
|
|
866
|
+
R,
|
|
867
|
+
const P extends ReadonlyArray<Types.PatternPrimitive<R> | Types.PatternBase<R>>,
|
|
868
|
+
Ret,
|
|
869
|
+
Args extends Array<any>,
|
|
870
|
+
Fn extends (_: Types.WhenMatch<R, P[number]>, ...args: Args) => Ret
|
|
871
|
+
>(...args: [...patterns: ExactPatterns<R, P>, f: Fn]) => internal.whenOr<R, P, Ret, Args, Fn>(...args)
|
|
846
872
|
|
|
847
873
|
/**
|
|
848
874
|
* Matches a value that satisfies all provided patterns.
|
|
@@ -890,7 +916,7 @@ export const whenAnd: <
|
|
|
890
916
|
Args extends Array<any>,
|
|
891
917
|
Fn extends (_: Types.WhenMatch<R, T.UnionToIntersection<P[number]>>, ...args: Args) => Ret
|
|
892
918
|
>(
|
|
893
|
-
...args: [...patterns:
|
|
919
|
+
...args: [...patterns: ExactPatterns<R, P>, f: Fn]
|
|
894
920
|
) => <I, F, A, Pr>(
|
|
895
921
|
self: Matcher<I, F, R, A, Pr, Ret, Args>
|
|
896
922
|
) => Matcher<
|
|
@@ -901,7 +927,13 @@ export const whenAnd: <
|
|
|
901
927
|
Pr,
|
|
902
928
|
Ret,
|
|
903
929
|
Args
|
|
904
|
-
> =
|
|
930
|
+
> = <
|
|
931
|
+
R,
|
|
932
|
+
const P extends ReadonlyArray<Types.PatternPrimitive<R> | Types.PatternBase<R>>,
|
|
933
|
+
Ret,
|
|
934
|
+
Args extends Array<any>,
|
|
935
|
+
Fn extends (_: Types.WhenMatch<R, T.UnionToIntersection<P[number]>>, ...args: Args) => Ret
|
|
936
|
+
>(...args: [...patterns: ExactPatterns<R, P>, f: Fn]) => internal.whenAnd<R, P, Ret, Args, Fn>(...args)
|
|
905
937
|
|
|
906
938
|
/**
|
|
907
939
|
* Matches values based on a specified discriminant field.
|
|
@@ -1398,7 +1430,7 @@ export const tagsExhaustive: <
|
|
|
1398
1430
|
*/
|
|
1399
1431
|
export const not: <
|
|
1400
1432
|
R,
|
|
1401
|
-
const P extends
|
|
1433
|
+
const P extends ExactPattern<R, P>,
|
|
1402
1434
|
Ret,
|
|
1403
1435
|
Args extends Array<any>,
|
|
1404
1436
|
Fn extends (_: Types.NotMatch<R, P>, ...args: Args) => Ret
|
|
@@ -2835,6 +2867,32 @@ export declare namespace Types {
|
|
|
2835
2867
|
|
|
2836
2868
|
type Simplify<A> = { [K in keyof A]: A[K] } & {}
|
|
2837
2869
|
|
|
2870
|
+
// Tuple patterns match a prefix at runtime. For inputs with a variadic part,
|
|
2871
|
+
// narrow each position the pattern requires and keep the rest of the input.
|
|
2872
|
+
type NarrowArrayPattern<I extends ReadonlyArray<any>, P extends ReadonlyArray<any>> = number extends I["length"]
|
|
2873
|
+
? number extends P["length"] ? MapArrayPattern<I, P>
|
|
2874
|
+
: P["length"] extends Required<P>["length"] ? NarrowArrayPrefix<I, P>
|
|
2875
|
+
: MapArrayPattern<I, P>
|
|
2876
|
+
: MapArrayPattern<I, P>
|
|
2877
|
+
|
|
2878
|
+
type MapArrayPattern<I, P> = {
|
|
2879
|
+
readonly [K in keyof I]: K extends keyof P ? ExtractAndNarrow<I[K], P[K]> : I[K]
|
|
2880
|
+
} extends infer R ? Fail extends R[keyof R] ? never
|
|
2881
|
+
: R
|
|
2882
|
+
: never
|
|
2883
|
+
|
|
2884
|
+
type NarrowArrayPrefix<
|
|
2885
|
+
I extends ReadonlyArray<any>,
|
|
2886
|
+
P extends ReadonlyArray<any>,
|
|
2887
|
+
Out extends ReadonlyArray<any> = readonly []
|
|
2888
|
+
> = P extends readonly [infer PH, ...infer PT] ?
|
|
2889
|
+
I extends readonly [infer IH, ...infer IT] ?
|
|
2890
|
+
[ExtractAndNarrow<IH, PH>] extends [infer N] ? [N] extends [never] ? never
|
|
2891
|
+
: NarrowArrayPrefix<IT, PT, readonly [...Out, N]>
|
|
2892
|
+
: never
|
|
2893
|
+
: NarrowArrayPrefix<readonly [I[number], ...Array<I[number]>], P, Out>
|
|
2894
|
+
: readonly [...Out, ...I]
|
|
2895
|
+
|
|
2838
2896
|
type ExtractAndNarrow<Input, P> = P extends Predicate.Refinement<infer _In, infer _Out> ?
|
|
2839
2897
|
_Out extends Input ? Extract<_Out, Input>
|
|
2840
2898
|
: Extract<Input, _Out> :
|
|
@@ -2843,12 +2901,7 @@ export declare namespace Types {
|
|
|
2843
2901
|
: Extract<Input, _In>
|
|
2844
2902
|
: P extends Predicate.Predicate<infer _In> ? Extract<Input, _In>
|
|
2845
2903
|
: Input extends infer I ? Exclude<
|
|
2846
|
-
I extends ReadonlyArray<any> ? P extends ReadonlyArray<any> ?
|
|
2847
|
-
readonly [K in keyof I]: K extends keyof P ? ExtractAndNarrow<I[K], P[K]>
|
|
2848
|
-
: I[K]
|
|
2849
|
-
} extends infer R ? Fail extends R[keyof R] ? never
|
|
2850
|
-
: R
|
|
2851
|
-
: never
|
|
2904
|
+
I extends ReadonlyArray<any> ? P extends ReadonlyArray<any> ? NarrowArrayPattern<I, P>
|
|
2852
2905
|
: never
|
|
2853
2906
|
: IsPlainObject<I> extends true ? string extends keyof I ? I extends P ? I
|
|
2854
2907
|
: never
|
package/src/Path.ts
CHANGED
|
@@ -14,6 +14,7 @@ import * as Context from "./Context.ts"
|
|
|
14
14
|
import * as Effect from "./Effect.ts"
|
|
15
15
|
import { identity } from "./Function.ts"
|
|
16
16
|
import * as Layer from "./Layer.ts"
|
|
17
|
+
import * as Option from "./Option.ts"
|
|
17
18
|
import { BadArgument } from "./PlatformError.ts"
|
|
18
19
|
|
|
19
20
|
/**
|
|
@@ -47,10 +48,17 @@ export const TypeId = "~effect/Path"
|
|
|
47
48
|
* formatting, and converting file system paths. URL conversion methods return
|
|
48
49
|
* `Effect`s because invalid file URLs or paths can fail with `BadArgument`.
|
|
49
50
|
*
|
|
51
|
+
* `resolveWithin(root, input)` resolves a relative `input` beneath `root` and
|
|
52
|
+
* returns `Option.none()` when the result would leave the root or when `input`
|
|
53
|
+
* has its own root (an absolute path, or a Windows drive or UNC prefix). The
|
|
54
|
+
* root itself is allowed. The check is lexical: it does not follow symlinks,
|
|
55
|
+
* so it is not a sandbox on its own. A relative `root` is resolved against the
|
|
56
|
+
* current working directory, as with `resolve`.
|
|
57
|
+
*
|
|
50
58
|
* **Example** (Using path operations)
|
|
51
59
|
*
|
|
52
60
|
* ```ts import.meta.vitest
|
|
53
|
-
* import { Effect, Path } from "effect"
|
|
61
|
+
* import { Effect, Option, Path } from "effect"
|
|
54
62
|
*
|
|
55
63
|
* const program = Effect.gen(function*() {
|
|
56
64
|
* const path = yield* Path.Path
|
|
@@ -64,7 +72,8 @@ export const TypeId = "~effect/Path"
|
|
|
64
72
|
* isAbsolute: path.isAbsolute("/absolute/path"),
|
|
65
73
|
* name: path.parse("/path/to/file.txt").name,
|
|
66
74
|
* relative: path.relative("/from/path", "/to/path"),
|
|
67
|
-
* resolved: path.resolve("/base", "relative", "path")
|
|
75
|
+
* resolved: path.resolve("/base", "relative", "path"),
|
|
76
|
+
* within: path.resolveWithin("/base", "../outside")
|
|
68
77
|
* }
|
|
69
78
|
* })
|
|
70
79
|
*
|
|
@@ -78,6 +87,7 @@ export const TypeId = "~effect/Path"
|
|
|
78
87
|
* result.name // => "file"
|
|
79
88
|
* result.relative // => "../../to/path"
|
|
80
89
|
* result.resolved // => "/base/relative/path"
|
|
90
|
+
* result.within // => Option.none()
|
|
81
91
|
* ```
|
|
82
92
|
*
|
|
83
93
|
* @stability unstable
|
|
@@ -98,6 +108,7 @@ export interface Path {
|
|
|
98
108
|
readonly parse: (path: string) => Path.Parsed
|
|
99
109
|
readonly relative: (from: string, to: string) => string
|
|
100
110
|
readonly resolve: (...pathSegments: ReadonlyArray<string>) => string
|
|
111
|
+
readonly resolveWithin: (root: string, input: string) => Option.Option<string>
|
|
101
112
|
readonly toFileUrl: (path: string) => Effect.Effect<URL, BadArgument>
|
|
102
113
|
readonly toNamespacedPath: (path: string) => string
|
|
103
114
|
}
|
|
@@ -204,8 +215,7 @@ export declare namespace Path {
|
|
|
204
215
|
* import { Effect, Layer, Path } from "effect"
|
|
205
216
|
*
|
|
206
217
|
* // Create a custom path implementation
|
|
207
|
-
* const customPath
|
|
208
|
-
* [Path.TypeId]: Path.TypeId,
|
|
218
|
+
* const customPath = Path.make({
|
|
209
219
|
* sep: "/",
|
|
210
220
|
* basename: (path: string, suffix?: string) => {
|
|
211
221
|
* const base = path.split("/").pop() || ""
|
|
@@ -239,7 +249,7 @@ export declare namespace Path {
|
|
|
239
249
|
* resolve: (...pathSegments: ReadonlyArray<string>) => pathSegments.join("/"),
|
|
240
250
|
* toFileUrl: (path: string) => Effect.succeed(new URL(`file://${path}`)),
|
|
241
251
|
* toNamespacedPath: (path: string) => path
|
|
242
|
-
* }
|
|
252
|
+
* })
|
|
243
253
|
*
|
|
244
254
|
* // Provide the path service
|
|
245
255
|
* const customPathLayer = Layer.succeed(Path.Path)(customPath)
|
|
@@ -259,6 +269,42 @@ export declare namespace Path {
|
|
|
259
269
|
*/
|
|
260
270
|
export const Path: Context.Service<Path, Path> = Context.Service("effect/Path")
|
|
261
271
|
|
|
272
|
+
/**
|
|
273
|
+
* Creates a `Path` service from platform path operations.
|
|
274
|
+
*
|
|
275
|
+
* **When to use**
|
|
276
|
+
*
|
|
277
|
+
* Use to build a `Path` implementation, such as a platform layer or a test
|
|
278
|
+
* double, without implementing the operations that can be derived from the
|
|
279
|
+
* others.
|
|
280
|
+
*
|
|
281
|
+
* **Details**
|
|
282
|
+
*
|
|
283
|
+
* Adds the `Path` type marker and derives `resolveWithin` from the provided
|
|
284
|
+
* `parse`, `resolve`, `relative`, `isAbsolute`, and `sep`, so containment
|
|
285
|
+
* follows the same platform rules as those operations.
|
|
286
|
+
*
|
|
287
|
+
* @see {@link layer} for the built-in POSIX `Path` service layer
|
|
288
|
+
*
|
|
289
|
+
* @stability unstable
|
|
290
|
+
* @category constructors
|
|
291
|
+
* @since 4.0.0
|
|
292
|
+
*/
|
|
293
|
+
export const make = (impl: Omit<Path, typeof TypeId | "resolveWithin">): Path =>
|
|
294
|
+
Path.of({
|
|
295
|
+
...impl,
|
|
296
|
+
[TypeId]: TypeId,
|
|
297
|
+
resolveWithin(root, input) {
|
|
298
|
+
if (impl.parse(input).root !== "") return Option.none()
|
|
299
|
+
const base = impl.resolve(root)
|
|
300
|
+
const candidate = impl.resolve(base, input)
|
|
301
|
+
const relative = impl.relative(base, candidate)
|
|
302
|
+
return relative === ".." || relative.startsWith(`..${impl.sep}`) || impl.isAbsolute(relative)
|
|
303
|
+
? Option.none()
|
|
304
|
+
: Option.some(candidate)
|
|
305
|
+
}
|
|
306
|
+
})
|
|
307
|
+
|
|
262
308
|
/**
|
|
263
309
|
* The following functions are adapted from the Node.js source code:
|
|
264
310
|
* https://github.com/nodejs/node/blob/main/lib/internal/url.js
|
|
@@ -479,8 +525,7 @@ function encodePathChars(filepath: string) {
|
|
|
479
525
|
return filepath
|
|
480
526
|
}
|
|
481
527
|
|
|
482
|
-
const posixImpl =
|
|
483
|
-
[TypeId]: TypeId,
|
|
528
|
+
const posixImpl = make({
|
|
484
529
|
resolve,
|
|
485
530
|
normalize(path) {
|
|
486
531
|
if (path.length === 0) return "."
|
package/src/Schema.ts
CHANGED
|
@@ -36,6 +36,7 @@ import * as HashMap_ from "./HashMap.ts"
|
|
|
36
36
|
import * as HashSet_ from "./HashSet.ts"
|
|
37
37
|
import * as Cookies_ from "./http/Cookies.ts"
|
|
38
38
|
import * as Headers_ from "./http/Headers.ts"
|
|
39
|
+
import * as UrlParams_internal from "./http/internal/urlParams.ts"
|
|
39
40
|
import * as UrlParams_ from "./http/UrlParams.ts"
|
|
40
41
|
import { NodeInspectSymbol } from "./Inspectable.ts"
|
|
41
42
|
import * as core from "./internal/core.ts"
|
|
@@ -5966,6 +5967,9 @@ export type DecodingDefaultOptions = {
|
|
|
5966
5967
|
function toIssueEffect<A, R>(
|
|
5967
5968
|
self: Effect.Effect<A, SchemaError, R>
|
|
5968
5969
|
): Effect.Effect<A, SchemaIssue.Issue, R> {
|
|
5970
|
+
if (effectIsExit(self) && self._tag === "Success") {
|
|
5971
|
+
return self as unknown as Exit_.Exit<A, SchemaIssue.Issue>
|
|
5972
|
+
}
|
|
5969
5973
|
return Effect.catchCause(self, (cause) => Effect.failCauseSync(() => Cause_.map(cause, (error) => error.issue)))
|
|
5970
5974
|
}
|
|
5971
5975
|
/**
|
|
@@ -6312,6 +6316,12 @@ type Flatten<Schemas> = Schemas extends readonly [infer Head, ...infer Tail]
|
|
|
6312
6316
|
? Head extends Union<infer Inner> ? [...Flatten<Inner>, ...Flatten<Tail>]
|
|
6313
6317
|
: [Head, ...Flatten<Tail>]
|
|
6314
6318
|
: []
|
|
6319
|
+
type DiscriminantKey<T extends PropertyKey> = T extends number ? `${T}` : T
|
|
6320
|
+
type EnsureUniqueDiscriminants<Tags extends ReadonlyArray<PropertyKey>, Seen = never> = Tags extends
|
|
6321
|
+
readonly [infer Head extends PropertyKey, ...infer Tail extends ReadonlyArray<PropertyKey>]
|
|
6322
|
+
? [DiscriminantKey<Head> & Seen] extends [never] ? EnsureUniqueDiscriminants<Tail, Seen | DiscriminantKey<Head>>
|
|
6323
|
+
: never
|
|
6324
|
+
: unknown
|
|
6315
6325
|
type MatchCasesResult<Cases> = {
|
|
6316
6326
|
[K in keyof Cases]-?: NonNullable<Cases[K]> extends (...args: Array<any>) => infer R ? R : never
|
|
6317
6327
|
}[keyof Cases]
|
|
@@ -6396,7 +6406,10 @@ export type toTaggedUnion<
|
|
|
6396
6406
|
*
|
|
6397
6407
|
* **Gotchas**
|
|
6398
6408
|
*
|
|
6399
|
-
*
|
|
6409
|
+
* Rejects overlapping discriminant types in known member tuples at compile
|
|
6410
|
+
* time, including nested unions. Numeric and string values such as `1` and
|
|
6411
|
+
* `"1"` count as duplicates. Also throws at runtime if multiple members use the
|
|
6412
|
+
* same discriminant property key.
|
|
6400
6413
|
*
|
|
6401
6414
|
* **Example** (Adding tagged-union utilities to an existing union)
|
|
6402
6415
|
*
|
|
@@ -6423,7 +6436,7 @@ export type toTaggedUnion<
|
|
|
6423
6436
|
*/
|
|
6424
6437
|
export function toTaggedUnion<const Tag extends PropertyKey>(tag: Tag) {
|
|
6425
6438
|
return <const Members extends ReadonlyArray<Constraint & { readonly Type: { readonly [K in Tag]: PropertyKey } }>>(
|
|
6426
|
-
self: Union<Members>
|
|
6439
|
+
self: Union<Members> & NoInfer<EnsureUniqueDiscriminants<TaggedUnionUtils<Tag, Members>["discriminants"]>>
|
|
6427
6440
|
): toTaggedUnion<Tag, Members> => {
|
|
6428
6441
|
const cases: Record<PropertyKey, unknown> = {}
|
|
6429
6442
|
const discriminants: Array<PropertyKey> = []
|
|
@@ -15221,9 +15234,9 @@ export const UrlParams: UrlParams = declare(
|
|
|
15221
15234
|
toCodec: () =>
|
|
15222
15235
|
link<UrlParams_.UrlParams>()(
|
|
15223
15236
|
ArraySchema(Tuple([String, String])),
|
|
15224
|
-
SchemaTransformation.transform({
|
|
15237
|
+
SchemaTransformation.transform<UrlParams_.UrlParams, ReadonlyArray<readonly [string, string]>>({
|
|
15225
15238
|
decode: UrlParams_.make,
|
|
15226
|
-
encode: (self) => self.params
|
|
15239
|
+
encode: (self) => self.params.map(([key, value]) => [key, UrlParams_internal.unwrap(value)])
|
|
15227
15240
|
})
|
|
15228
15241
|
)
|
|
15229
15242
|
}
|
package/src/String.ts
CHANGED
|
@@ -1441,6 +1441,12 @@ export const stripMargin = (self: string): string => stripMarginWith(self, "|")
|
|
|
1441
1441
|
/**
|
|
1442
1442
|
* Converts a snake_case string to camelCase.
|
|
1443
1443
|
*
|
|
1444
|
+
* **Details**
|
|
1445
|
+
*
|
|
1446
|
+
* Keeps the first character, then replaces each later underscore and the
|
|
1447
|
+
* character after it with that character uppercased. A trailing underscore is
|
|
1448
|
+
* dropped. Input made only of an even number of underscores returns `""`.
|
|
1449
|
+
*
|
|
1444
1450
|
* **Example** (Converting snake_case to camelCase)
|
|
1445
1451
|
*
|
|
1446
1452
|
* ```ts import.meta.vitest
|
|
@@ -1455,10 +1461,10 @@ export const stripMargin = (self: string): string => stripMarginWith(self, "|")
|
|
|
1455
1461
|
* @since 2.0.0
|
|
1456
1462
|
*/
|
|
1457
1463
|
export const snakeToCamel = (self: string): string => {
|
|
1458
|
-
if (self.length === 0) return
|
|
1464
|
+
if (self.length === 0 || (self.length % 2 === 0 && self[0] === "_" && /^_+$/.test(self))) return ""
|
|
1459
1465
|
let str = self[0]
|
|
1460
1466
|
for (let i = 1; i < self.length; i++) {
|
|
1461
|
-
str += self[i] === "_" ? self
|
|
1467
|
+
str += self[i] === "_" ? self.charAt(++i).toUpperCase() : self[i]
|
|
1462
1468
|
}
|
|
1463
1469
|
return str
|
|
1464
1470
|
}
|
|
@@ -1466,6 +1472,12 @@ export const snakeToCamel = (self: string): string => {
|
|
|
1466
1472
|
/**
|
|
1467
1473
|
* Converts a snake_case string to PascalCase.
|
|
1468
1474
|
*
|
|
1475
|
+
* **Details**
|
|
1476
|
+
*
|
|
1477
|
+
* Uppercases the first character, then replaces each later underscore and the
|
|
1478
|
+
* character after it with that character uppercased. A trailing underscore is
|
|
1479
|
+
* dropped. Input made only of an even number of underscores returns `""`.
|
|
1480
|
+
*
|
|
1469
1481
|
* **Example** (Converting snake_case to PascalCase)
|
|
1470
1482
|
*
|
|
1471
1483
|
* ```ts import.meta.vitest
|
|
@@ -1480,10 +1492,10 @@ export const snakeToCamel = (self: string): string => {
|
|
|
1480
1492
|
* @since 2.0.0
|
|
1481
1493
|
*/
|
|
1482
1494
|
export const snakeToPascal = (self: string): string => {
|
|
1483
|
-
if (self.length === 0) return
|
|
1495
|
+
if (self.length === 0 || (self.length % 2 === 0 && self[0] === "_" && /^_+$/.test(self))) return ""
|
|
1484
1496
|
let str = self[0].toUpperCase()
|
|
1485
1497
|
for (let i = 1; i < self.length; i++) {
|
|
1486
|
-
str += self[i] === "_" ? self
|
|
1498
|
+
str += self[i] === "_" ? self.charAt(++i).toUpperCase() : self[i]
|
|
1487
1499
|
}
|
|
1488
1500
|
return str
|
|
1489
1501
|
}
|
|
@@ -1739,6 +1751,7 @@ const normalizeCase = (
|
|
|
1739
1751
|
while (result.charAt(end - 1) === "\0") {
|
|
1740
1752
|
end--
|
|
1741
1753
|
}
|
|
1754
|
+
if (start >= end) return ""
|
|
1742
1755
|
|
|
1743
1756
|
// Transform each token independently.
|
|
1744
1757
|
return result.slice(start, end).split("\0").map(transform).join(delimiter)
|
package/src/TxRef.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* @since 4.0.0
|
|
14
14
|
*/
|
|
15
15
|
import * as Effect from "./Effect.ts"
|
|
16
|
+
import type { TransactionMetaInner } from "./Effect.ts"
|
|
16
17
|
import { dual } from "./Function.ts"
|
|
17
18
|
import { pipeArguments } from "./Pipeable.ts"
|
|
18
19
|
import type { Pipeable } from "./Pipeable.ts"
|
|
@@ -140,10 +141,11 @@ export const makeUnsafe = <A>(initial: A): TxRef<A> => ({
|
|
|
140
141
|
})
|
|
141
142
|
|
|
142
143
|
const journalEntry = <A>(state: Effect.Transaction["Service"], self: TxRef<A>) => {
|
|
143
|
-
|
|
144
|
+
const journal = (state as TransactionMetaInner).journal
|
|
145
|
+
let entry = journal.get(self)
|
|
144
146
|
if (entry === undefined) {
|
|
145
147
|
entry = { version: self.version, value: self.value, written: false }
|
|
146
|
-
|
|
148
|
+
journal.set(self, entry)
|
|
147
149
|
}
|
|
148
150
|
return entry
|
|
149
151
|
}
|
package/src/ai/AiError.ts
CHANGED
|
@@ -47,7 +47,9 @@ import * as Schema from "../Schema.ts"
|
|
|
47
47
|
export const HttpRequestDetails = Schema.Struct({
|
|
48
48
|
method: Schema.Literals(["GET", "POST", "PATCH", "PUT", "DELETE", "HEAD", "OPTIONS", "TRACE", "QUERY"]),
|
|
49
49
|
url: Schema.String,
|
|
50
|
-
urlParams: Schema.Array(
|
|
50
|
+
urlParams: Schema.Array(
|
|
51
|
+
Schema.Tuple([Schema.String, Schema.Union([Schema.String, Schema.Redacted(Schema.String)])])
|
|
52
|
+
),
|
|
51
53
|
hash: Schema.optional(Schema.String),
|
|
52
54
|
headers: Schema.Record(
|
|
53
55
|
Schema.String,
|
package/src/ai/Decision.ts
CHANGED
|
@@ -28,9 +28,23 @@ export type TypeId = "~effect/ai/Decision"
|
|
|
28
28
|
*/
|
|
29
29
|
export const TypeId: TypeId = "~effect/ai/Decision"
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Decision instructions or descriptions: a string, JSON object, or JSON array.
|
|
33
|
+
*
|
|
34
|
+
* **Details**
|
|
35
|
+
*
|
|
36
|
+
* TypeScript interfaces lack the index signature required by `Schema.JsonObject`;
|
|
37
|
+
* use object literals, type aliases, or Schema types instead.
|
|
38
|
+
*
|
|
39
|
+
* @stability unstable
|
|
40
|
+
* @category models
|
|
41
|
+
* @since 4.0.5
|
|
42
|
+
*/
|
|
43
|
+
export type Description = string | Schema.JsonObject | Schema.JsonArray
|
|
44
|
+
|
|
31
45
|
/**
|
|
32
46
|
* Decision that assigns the input one label out of a set of criteria.
|
|
33
|
-
* `criteria` maps labels to descriptions.
|
|
47
|
+
* `criteria` maps labels to descriptions; use `null` for a label without a description.
|
|
34
48
|
*
|
|
35
49
|
* @see {@link classify} for the constructor
|
|
36
50
|
* @see {@link ClassifyAnswer} for the answer produced by this decision
|
|
@@ -41,13 +55,14 @@ export const TypeId: TypeId = "~effect/ai/Decision"
|
|
|
41
55
|
*/
|
|
42
56
|
export interface Classify<Label extends string> {
|
|
43
57
|
readonly _tag: "Classify"
|
|
44
|
-
readonly instructions:
|
|
45
|
-
readonly criteria: { readonly [L in Label]:
|
|
58
|
+
readonly instructions: Description
|
|
59
|
+
readonly criteria: { readonly [L in Label]: Description | null }
|
|
46
60
|
}
|
|
47
61
|
|
|
48
62
|
/**
|
|
49
63
|
* Decision that places the input on an ordered scale of criteria.
|
|
50
|
-
* `criteria` lists levels from lowest to highest
|
|
64
|
+
* `criteria` lists levels from lowest to highest, with labels for answers and
|
|
65
|
+
* descriptions for the provider.
|
|
51
66
|
*
|
|
52
67
|
* @see {@link rate} for the constructor
|
|
53
68
|
* @see {@link RateAnswer} for the answer produced by this decision
|
|
@@ -58,8 +73,8 @@ export interface Classify<Label extends string> {
|
|
|
58
73
|
*/
|
|
59
74
|
export interface Rate<Level extends string> {
|
|
60
75
|
readonly _tag: "Rate"
|
|
61
|
-
readonly instructions:
|
|
62
|
-
readonly criteria: ReadonlyArray<Level>
|
|
76
|
+
readonly instructions: Description
|
|
77
|
+
readonly criteria: ReadonlyArray<{ readonly label: Level; readonly description: Description }>
|
|
63
78
|
}
|
|
64
79
|
|
|
65
80
|
/**
|
|
@@ -76,10 +91,10 @@ export interface Rate<Level extends string> {
|
|
|
76
91
|
*/
|
|
77
92
|
export interface Probability {
|
|
78
93
|
readonly _tag: "Probability"
|
|
79
|
-
readonly instructions:
|
|
94
|
+
readonly instructions: Description
|
|
80
95
|
readonly criteria?: {
|
|
81
|
-
readonly false:
|
|
82
|
-
readonly true:
|
|
96
|
+
readonly false: Description
|
|
97
|
+
readonly true: Description
|
|
83
98
|
} | undefined
|
|
84
99
|
}
|
|
85
100
|
|
|
@@ -110,8 +125,9 @@ export interface ClassifyAnswer<Label extends string> {
|
|
|
110
125
|
/**
|
|
111
126
|
* Answer to a {@link Rate} decision.
|
|
112
127
|
* `rating` is the probability-weighted position on the scale and may fall
|
|
113
|
-
* between two levels, within `[0, criteria.length - 1]`. `label` is the
|
|
114
|
-
* with the highest probability, choosing the first criteria entry
|
|
128
|
+
* between two levels, within `[0, criteria.length - 1]`. `label` is the label
|
|
129
|
+
* of the level with the highest probability, choosing the first criteria entry
|
|
130
|
+
* on ties.
|
|
115
131
|
* `confidence` is an optional, provider-defined measure in `[0, 1]`.
|
|
116
132
|
*
|
|
117
133
|
* @stability unstable
|
|
@@ -176,6 +192,7 @@ export interface Definition<Input extends Schema.Constraint, Decisions extends R
|
|
|
176
192
|
|
|
177
193
|
/**
|
|
178
194
|
* Creates a classification decision from labelled criteria.
|
|
195
|
+
* Descriptions can be `null` when the label needs no explanation.
|
|
179
196
|
* Throws if fewer than two labels are supplied.
|
|
180
197
|
*
|
|
181
198
|
* **Example** (Choosing a department)
|
|
@@ -201,8 +218,8 @@ export interface Definition<Input extends Schema.Constraint, Decisions extends R
|
|
|
201
218
|
* @since 4.0.0
|
|
202
219
|
*/
|
|
203
220
|
export const classify = <Label extends string>(options: {
|
|
204
|
-
readonly instructions:
|
|
205
|
-
readonly criteria: { readonly [L in Label]:
|
|
221
|
+
readonly instructions: Description
|
|
222
|
+
readonly criteria: { readonly [L in Label]: Description | null }
|
|
206
223
|
}): Classify<Label> => {
|
|
207
224
|
if (Object.keys(options.criteria).length < 2) {
|
|
208
225
|
throw new Error("Decision.classify: criteria must contain at least two labels")
|
|
@@ -216,7 +233,9 @@ export const classify = <Label extends string>(options: {
|
|
|
216
233
|
|
|
217
234
|
/**
|
|
218
235
|
* Creates a rating decision from an ordered list of criteria.
|
|
219
|
-
*
|
|
236
|
+
* Strings serve as both label and description; use `{ label, description }`
|
|
237
|
+
* to separate them. Answers use the label.
|
|
238
|
+
* Throws if fewer than two levels or duplicate labels are supplied.
|
|
220
239
|
*
|
|
221
240
|
* **Example** (Rating frustration)
|
|
222
241
|
*
|
|
@@ -229,6 +248,33 @@ export const classify = <Label extends string>(options: {
|
|
|
229
248
|
* })
|
|
230
249
|
* ```
|
|
231
250
|
*
|
|
251
|
+
* **Example** (Describing levels with structure)
|
|
252
|
+
*
|
|
253
|
+
* ```ts
|
|
254
|
+
* import { Decision } from "effect/ai"
|
|
255
|
+
*
|
|
256
|
+
* const severity = Decision.rate({
|
|
257
|
+
* instructions: "How severe is the reported issue?",
|
|
258
|
+
* criteria: [
|
|
259
|
+
* "cosmetic",
|
|
260
|
+
* {
|
|
261
|
+
* label: "degraded",
|
|
262
|
+
* description: {
|
|
263
|
+
* what: "Broken or degraded feature, but workaround exists",
|
|
264
|
+
* examples: ["export fails in one browser but works in another"]
|
|
265
|
+
* }
|
|
266
|
+
* },
|
|
267
|
+
* {
|
|
268
|
+
* label: "blocking",
|
|
269
|
+
* description: {
|
|
270
|
+
* what: "Blocking issue; no workaround exists",
|
|
271
|
+
* examples: ["cannot log in", "data loss"]
|
|
272
|
+
* }
|
|
273
|
+
* }
|
|
274
|
+
* ]
|
|
275
|
+
* })
|
|
276
|
+
* ```
|
|
277
|
+
*
|
|
232
278
|
* @see {@link classify} for unordered labels
|
|
233
279
|
*
|
|
234
280
|
* @stability unstable
|
|
@@ -236,19 +282,22 @@ export const classify = <Label extends string>(options: {
|
|
|
236
282
|
* @since 4.0.0
|
|
237
283
|
*/
|
|
238
284
|
export const rate = <const Level extends string>(options: {
|
|
239
|
-
readonly instructions:
|
|
240
|
-
readonly criteria: ReadonlyArray<Level>
|
|
285
|
+
readonly instructions: Description
|
|
286
|
+
readonly criteria: ReadonlyArray<Level | { readonly label: Level; readonly description: Description }>
|
|
241
287
|
}): Rate<Level> => {
|
|
242
288
|
if (options.criteria.length < 2) {
|
|
243
289
|
throw new Error("Decision.rate: criteria must contain at least two levels")
|
|
244
290
|
}
|
|
245
|
-
|
|
291
|
+
const criteria = options.criteria.map((level) =>
|
|
292
|
+
typeof level === "string" ? { label: level, description: level } : level
|
|
293
|
+
)
|
|
294
|
+
if (new Set(criteria.map((level) => level.label)).size !== criteria.length) {
|
|
246
295
|
throw new Error("Decision.rate: criteria must contain distinct levels")
|
|
247
296
|
}
|
|
248
297
|
return {
|
|
249
298
|
_tag: "Rate",
|
|
250
299
|
instructions: options.instructions,
|
|
251
|
-
criteria
|
|
300
|
+
criteria
|
|
252
301
|
}
|
|
253
302
|
}
|
|
254
303
|
|
|
@@ -287,10 +336,10 @@ export const rate = <const Level extends string>(options: {
|
|
|
287
336
|
* @since 4.0.0
|
|
288
337
|
*/
|
|
289
338
|
export const probability = (options: {
|
|
290
|
-
readonly instructions:
|
|
339
|
+
readonly instructions: Description
|
|
291
340
|
readonly criteria?: {
|
|
292
|
-
readonly false:
|
|
293
|
-
readonly true:
|
|
341
|
+
readonly false: Description
|
|
342
|
+
readonly true: Description
|
|
294
343
|
} | undefined
|
|
295
344
|
}): Probability => ({
|
|
296
345
|
_tag: "Probability",
|
package/src/ai/DecisionModel.ts
CHANGED
|
@@ -290,7 +290,7 @@ const validateAnswer = (
|
|
|
290
290
|
return { label: answer.label, probabilities, ...(confidence === undefined ? undefined : { confidence }) }
|
|
291
291
|
}
|
|
292
292
|
case "Rate": {
|
|
293
|
-
const levels = decision.criteria
|
|
293
|
+
const levels = decision.criteria.map((level) => level.label)
|
|
294
294
|
if (!isFiniteNumber(answer.rating) || answer.rating < 0 || answer.rating > levels.length - 1) {
|
|
295
295
|
return invalidOutput(`Provider returned a rating outside [0, ${levels.length - 1}] for decision "${key}"`)
|
|
296
296
|
}
|