resultar 3.6.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -673,6 +673,897 @@ const runSync = (result) => result.unwrapOrThrow();
673
673
  /** Compatibility alias. Prefer `tryResult` in new code. */
674
674
  const tryCatch = tryResult;
675
675
  //#endregion
676
+ //#region src/task/scope.ts
677
+ /** Appends cleanup failures without replacing the original execution outcome. */
678
+ const appendExit = (exit, cleanup) => {
679
+ if (cleanup._tag === "Success") return exit;
680
+ if (exit._tag === "Success") return cleanup;
681
+ return {
682
+ _tag: "Failure",
683
+ cause: {
684
+ _tag: "Sequential",
685
+ left: exit.cause,
686
+ right: cleanup.cause
687
+ }
688
+ };
689
+ };
690
+ /** Private runtime scope; each run owns its own finalizer stack. */
691
+ var TaskScope = class {
692
+ finalizers = [];
693
+ closing;
694
+ add(finalizer) {
695
+ if (this.closing !== void 0) throw new Error("Cannot acquire into a closing ResultTask scope");
696
+ this.finalizers.push(finalizer);
697
+ }
698
+ adopt(child) {
699
+ if (this.closing !== void 0) throw new Error("Cannot acquire into a closing ResultTask scope");
700
+ this.finalizers.push(...child.finalizers.splice(0));
701
+ }
702
+ close(exit, cleanupOnly = false) {
703
+ this.closing ??= this.drain(exit, cleanupOnly);
704
+ return this.closing;
705
+ }
706
+ async drain(exit, cleanupOnly) {
707
+ let result = cleanupOnly ? {
708
+ _tag: "Success",
709
+ value: void 0
710
+ } : exit;
711
+ let finalizer = this.finalizers.pop();
712
+ while (finalizer !== void 0) {
713
+ try {
714
+ result = appendExit(result, await finalizer(exit));
715
+ } catch (error) {
716
+ result = appendExit(result, {
717
+ _tag: "Failure",
718
+ cause: {
719
+ _tag: "Die",
720
+ defect: error
721
+ }
722
+ });
723
+ }
724
+ finalizer = this.finalizers.pop();
725
+ }
726
+ return result;
727
+ }
728
+ };
729
+ //#endregion
730
+ //#region src/result-task.ts
731
+ /** Rejection used when a simplified boundary cannot represent multiple failures. */
732
+ var ResultTaskCauseError = class extends Error {
733
+ cause;
734
+ constructor(cause) {
735
+ super("ResultTask execution failed with multiple causes");
736
+ this.name = "ResultTaskCauseError";
737
+ Object.defineProperty(this, "cause", {
738
+ configurable: true,
739
+ enumerable: false,
740
+ value: cause,
741
+ writable: true
742
+ });
743
+ }
744
+ };
745
+ /** Type identifier symbol for nominal `ResultTask` branding and variance checks. */
746
+ const ResultTaskTypeId = Symbol.for("resultar/ResultTask");
747
+ /** Type identifier symbol for nominal `ServiceTag` branding. */
748
+ const ServiceTagTypeId = Symbol.for("resultar/ServiceTag");
749
+ /** Type identifier symbol for nominal `ResultTask` yieldable objects. */
750
+ const ResultTaskYieldTypeId = Symbol.for("resultar/ResultTaskYield");
751
+ /** Error thrown as a Die cause when a requested service is not provided in the environment. */
752
+ var MissingServiceError = class extends Error {
753
+ serviceIdentifier;
754
+ constructor(serviceIdentifier) {
755
+ super(`Missing ResultTask service: ${serviceIdentifier}`);
756
+ this.name = "MissingServiceError";
757
+ this.serviceIdentifier = serviceIdentifier;
758
+ }
759
+ };
760
+ const success = (value) => ({
761
+ _tag: "Success",
762
+ value
763
+ });
764
+ const failure = (cause) => ({
765
+ _tag: "Failure",
766
+ cause
767
+ });
768
+ const failed = (error) => failure({
769
+ _tag: "Fail",
770
+ error
771
+ });
772
+ const died = (defect) => failure({
773
+ _tag: "Die",
774
+ defect
775
+ });
776
+ const interrupted = (signal) => failure({
777
+ _tag: "Interrupt",
778
+ reason: signal.reason
779
+ });
780
+ const interruptSuccess = (exit, signal) => exit._tag === "Success" && signal.aborted ? interrupted(signal) : exit;
781
+ const throwDefect = (defect) => {
782
+ throw defect;
783
+ };
784
+ const isObjectLike = (value) => (typeof value === "object" || typeof value === "function") && value !== null;
785
+ const isPlainRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
786
+ /** Returns true if a value is a nominal `ServiceTag`. */
787
+ const isServiceTag = (value) => isObjectLike(value) && value[ServiceTagTypeId] === ServiceTagTypeId && value._tag === "ServiceTag" && typeof value.identifier === "string" && typeof value.key === "symbol" && typeof value[Symbol.iterator] === "function";
788
+ /** Returns true if a value is a `ResultTask` instance. */
789
+ const isResultTask = (value) => isObjectLike(value) && (value instanceof ResultTask || value[ResultTaskTypeId] !== void 0);
790
+ const isResultTaskYield = (value) => isObjectLike(value) && value[ResultTaskYieldTypeId] === ResultTaskYieldTypeId && value._tag === "ResultTask" && isResultTask(value.task);
791
+ const isServiceYield = (value) => isObjectLike(value) && value[ResultTaskYieldTypeId] === ResultTaskYieldTypeId && value._tag === "Service" && isServiceTag(value.tag);
792
+ const isErrResult = (value) => isObjectLike(value) && "error" in value && typeof value.isErr === "function" && value.isErr();
793
+ const lookupService = (tag, context) => {
794
+ if (context.services.has(tag.key)) return {
795
+ _tag: "Found",
796
+ value: context.services.get(tag.key)
797
+ };
798
+ if (context.namedServices.has(tag.identifier)) return {
799
+ _tag: "Found",
800
+ value: context.namedServices.get(tag.identifier)
801
+ };
802
+ return { _tag: "Missing" };
803
+ };
804
+ const resolveService = async (tag, context, executeTask) => {
805
+ const supplied = lookupService(tag, context);
806
+ if (supplied._tag === "Found") return supplied;
807
+ if (context.serviceResolver === void 0) return supplied;
808
+ let task = void 0;
809
+ try {
810
+ task = context.serviceResolver(tag);
811
+ } catch (error) {
812
+ return {
813
+ _tag: "Error",
814
+ error
815
+ };
816
+ }
817
+ if (task === void 0) return supplied;
818
+ const outcome = await executeTaskSafely(task, executeTask);
819
+ if ("error" in outcome) return {
820
+ _tag: "Error",
821
+ error: outcome.error
822
+ };
823
+ if (outcome._tag === "Failure") return {
824
+ _tag: "Failure",
825
+ exit: outcome
826
+ };
827
+ return {
828
+ _tag: "Found",
829
+ value: outcome.value
830
+ };
831
+ };
832
+ const executeTaskSafely = async (task, executeTask) => {
833
+ try {
834
+ return await executeTask(task);
835
+ } catch (error) {
836
+ return { error };
837
+ }
838
+ };
839
+ const closeGenerator = async (iterator, exit, runtime) => {
840
+ try {
841
+ let step = iterator.return(void 0);
842
+ let finalExit = exit;
843
+ while (step.done === false) if (isResultTaskYield(step.value)) {
844
+ const outcome = await executeTaskSafely(step.value.task, runtime.executeTask);
845
+ if ("error" in outcome) {
846
+ finalExit = died(outcome.error);
847
+ step = iterator.return(void 0);
848
+ } else if (outcome._tag === "Failure") {
849
+ finalExit = outcome;
850
+ step = iterator.return(void 0);
851
+ } else step = iterator.next(outcome);
852
+ } else if (isServiceYield(step.value)) {
853
+ const resolution = await resolveService(step.value.tag, runtime.context, runtime.executeTask);
854
+ if (resolution._tag === "Found") step = iterator.next(resolution.value);
855
+ else if (resolution._tag === "Failure") {
856
+ finalExit = resolution.exit;
857
+ step = iterator.return(void 0);
858
+ } else {
859
+ finalExit = died(resolution._tag === "Error" ? resolution.error : new MissingServiceError(step.value.tag.identifier));
860
+ step = iterator.return(void 0);
861
+ }
862
+ } else if (isErrResult(step.value)) {
863
+ finalExit = failed(step.value.error);
864
+ step = iterator.return(void 0);
865
+ } else {
866
+ finalExit = died(/* @__PURE__ */ new TypeError("ResultTask.gen yielded an unsupported value"));
867
+ step = iterator.return(void 0);
868
+ }
869
+ return finalExit;
870
+ } catch (error) {
871
+ return died(error);
872
+ }
873
+ };
874
+ const withServices = (context, services) => ({
875
+ scope: context.scope,
876
+ namedServices: context.namedServices,
877
+ services,
878
+ serviceResolver: context.serviceResolver,
879
+ signal: context.signal
880
+ });
881
+ const withScope = (context, scope, signal = context.signal) => ({
882
+ namedServices: context.namedServices,
883
+ services: context.services,
884
+ serviceResolver: context.serviceResolver,
885
+ signal,
886
+ scope
887
+ });
888
+ const withNamedServices = (context, namedServices) => ({
889
+ scope: context.scope,
890
+ namedServices,
891
+ services: context.services,
892
+ serviceResolver: context.serviceResolver,
893
+ signal: context.signal
894
+ });
895
+ const withServiceResolver = (context, serviceResolver) => ({
896
+ namedServices: context.namedServices,
897
+ services: context.services,
898
+ serviceResolver,
899
+ signal: context.signal,
900
+ scope: context.scope
901
+ });
902
+ var ServiceTagValue = class {
903
+ [ServiceTagTypeId] = ServiceTagTypeId;
904
+ _tag = "ServiceTag";
905
+ identifier;
906
+ key;
907
+ constructor(identifier) {
908
+ this.identifier = identifier;
909
+ this.key = Symbol(identifier);
910
+ }
911
+ *[Symbol.iterator]() {
912
+ return yield {
913
+ [ResultTaskYieldTypeId]: ResultTaskYieldTypeId,
914
+ _tag: "Service",
915
+ tag: this
916
+ };
917
+ }
918
+ };
919
+ /** Creates a service tag that can be requested with `yield*` inside `ResultTask.gen`. */
920
+ const serviceTag = (identifier) => new ServiceTagValue(identifier);
921
+ const applySuccessContinuation = (continuation, exit) => {
922
+ switch (continuation._tag) {
923
+ case "Map": try {
924
+ return {
925
+ current: void 0,
926
+ currentExit: success(continuation.f(exit.value))
927
+ };
928
+ } catch (error) {
929
+ return {
930
+ current: void 0,
931
+ currentExit: died(error)
932
+ };
933
+ }
934
+ case "FlatMap": try {
935
+ return {
936
+ current: continuation.f(exit.value),
937
+ currentExit: void 0
938
+ };
939
+ } catch (error) {
940
+ return {
941
+ current: void 0,
942
+ currentExit: died(error)
943
+ };
944
+ }
945
+ case "Tap": try {
946
+ const res = continuation.f(exit.value);
947
+ return ResultTask.toTapContinuationStep(res, () => ResultTask.succeed(exit.value), exit);
948
+ } catch (error) {
949
+ return {
950
+ current: void 0,
951
+ currentExit: died(error)
952
+ };
953
+ }
954
+ case "MapError": return {
955
+ current: void 0,
956
+ currentExit: exit
957
+ };
958
+ case "TapError": return {
959
+ current: void 0,
960
+ currentExit: exit
961
+ };
962
+ case "CatchAll": return {
963
+ current: void 0,
964
+ currentExit: exit
965
+ };
966
+ default: return {
967
+ current: void 0,
968
+ currentExit: exit
969
+ };
970
+ }
971
+ };
972
+ const applyFailureContinuation = (continuation, exit) => {
973
+ switch (continuation._tag) {
974
+ case "MapError":
975
+ if (exit.cause._tag === "Fail") try {
976
+ return {
977
+ current: void 0,
978
+ currentExit: failed(continuation.f(exit.cause.error))
979
+ };
980
+ } catch (error) {
981
+ return {
982
+ current: void 0,
983
+ currentExit: died(error)
984
+ };
985
+ }
986
+ return {
987
+ current: void 0,
988
+ currentExit: exit
989
+ };
990
+ case "TapError":
991
+ if (exit.cause._tag === "Fail") try {
992
+ const failError = exit.cause.error;
993
+ const res = continuation.f(failError);
994
+ return ResultTask.toTapContinuationStep(res, () => ResultTask.fail(failError), exit);
995
+ } catch (error) {
996
+ return {
997
+ current: void 0,
998
+ currentExit: died(error)
999
+ };
1000
+ }
1001
+ return {
1002
+ current: void 0,
1003
+ currentExit: exit
1004
+ };
1005
+ case "CatchAll":
1006
+ if (exit.cause._tag === "Sequential") return {
1007
+ current: void 0,
1008
+ currentExit: died(new ResultTaskCauseError(exit.cause))
1009
+ };
1010
+ if (exit.cause._tag === "Fail") try {
1011
+ return {
1012
+ current: continuation.f(exit.cause.error),
1013
+ currentExit: void 0
1014
+ };
1015
+ } catch (error) {
1016
+ return {
1017
+ current: void 0,
1018
+ currentExit: died(error)
1019
+ };
1020
+ }
1021
+ return {
1022
+ current: void 0,
1023
+ currentExit: exit
1024
+ };
1025
+ case "Map": return {
1026
+ current: void 0,
1027
+ currentExit: exit
1028
+ };
1029
+ case "FlatMap": return {
1030
+ current: void 0,
1031
+ currentExit: exit
1032
+ };
1033
+ case "Tap": return {
1034
+ current: void 0,
1035
+ currentExit: exit
1036
+ };
1037
+ default: return {
1038
+ current: void 0,
1039
+ currentExit: exit
1040
+ };
1041
+ }
1042
+ };
1043
+ const applyContinuation = (continuation, exit) => exit._tag === "Success" ? applySuccessContinuation(continuation, exit) : applyFailureContinuation(continuation, exit);
1044
+ const executeInstruction = async (instruction, continuations, context) => {
1045
+ switch (instruction._tag) {
1046
+ case "FlatMap":
1047
+ case "Map":
1048
+ case "MapError":
1049
+ case "Tap":
1050
+ case "TapError":
1051
+ case "CatchAll":
1052
+ continuations.push(instruction);
1053
+ return {
1054
+ nextCurrent: instruction.task,
1055
+ exit: void 0
1056
+ };
1057
+ case "Succeed": return {
1058
+ nextCurrent: void 0,
1059
+ exit: success(instruction.value)
1060
+ };
1061
+ case "Fail": return {
1062
+ nextCurrent: void 0,
1063
+ exit: failed(instruction.error)
1064
+ };
1065
+ case "Sync": try {
1066
+ return {
1067
+ nextCurrent: void 0,
1068
+ exit: instruction.evaluate()
1069
+ };
1070
+ } catch (error) {
1071
+ return {
1072
+ nextCurrent: void 0,
1073
+ exit: died(error)
1074
+ };
1075
+ }
1076
+ case "Async": try {
1077
+ return {
1078
+ nextCurrent: void 0,
1079
+ exit: await instruction.execute(context)
1080
+ };
1081
+ } catch (error) {
1082
+ return {
1083
+ nextCurrent: void 0,
1084
+ exit: died(error)
1085
+ };
1086
+ }
1087
+ default: return {
1088
+ nextCurrent: void 0,
1089
+ exit: void 0
1090
+ };
1091
+ }
1092
+ };
1093
+ var ResultTask = class ResultTask extends Pipeable {
1094
+ instruction;
1095
+ execute;
1096
+ constructor(instructionOrExecute) {
1097
+ super();
1098
+ this.instruction = typeof instructionOrExecute === "function" ? {
1099
+ _tag: "Async",
1100
+ execute: instructionOrExecute
1101
+ } : instructionOrExecute;
1102
+ this.execute = (context) => ResultTask.runTaskLoop(this, context);
1103
+ }
1104
+ /** @internal */
1105
+ static toTapContinuationStep(res, onSuccess, passThroughExit) {
1106
+ if (res instanceof ResultTask) return {
1107
+ current: res.flatMap(onSuccess),
1108
+ currentExit: void 0
1109
+ };
1110
+ if (typeof res === "object" && res !== null && typeof res.then === "function") return {
1111
+ current: new ResultTask(async () => {
1112
+ try {
1113
+ await res;
1114
+ return success(void 0);
1115
+ } catch (error) {
1116
+ return died(error);
1117
+ }
1118
+ }).flatMap(onSuccess),
1119
+ currentExit: void 0
1120
+ };
1121
+ return {
1122
+ current: void 0,
1123
+ currentExit: passThroughExit
1124
+ };
1125
+ }
1126
+ static async runTaskLoop(rootTask, context) {
1127
+ const continuations = [];
1128
+ let current = rootTask;
1129
+ let currentExit = void 0;
1130
+ while (current !== void 0 || continuations.length > 0) if (current === void 0) {
1131
+ if (currentExit !== void 0) {
1132
+ const nextContinuation = continuations.pop();
1133
+ if (nextContinuation === void 0) return currentExit;
1134
+ const resolvedExit = context.signal.aborted && currentExit._tag === "Success" ? interrupted(context.signal) : currentExit;
1135
+ const step = applyContinuation(nextContinuation, resolvedExit);
1136
+ current = step.current;
1137
+ currentExit = step.currentExit;
1138
+ }
1139
+ } else {
1140
+ if (context.signal.aborted) return interrupted(context.signal);
1141
+ const step = await executeInstruction(current.instruction, continuations, context);
1142
+ current = step.nextCurrent;
1143
+ currentExit = step.exit;
1144
+ }
1145
+ return currentExit ?? success(void 0);
1146
+ }
1147
+ static succeed(value) {
1148
+ return new ResultTask({
1149
+ _tag: "Succeed",
1150
+ value
1151
+ });
1152
+ }
1153
+ /** Creates a task that fails with `error` when it is executed. */
1154
+ static fail(error) {
1155
+ return new ResultTask({
1156
+ _tag: "Fail",
1157
+ error
1158
+ });
1159
+ }
1160
+ /** Lifts an already computed Result into a lazy task. */
1161
+ static fromResult(result) {
1162
+ return new ResultTask({
1163
+ _tag: "Sync",
1164
+ evaluate: () => result.isOk() ? success(result.value) : failed(result.error)
1165
+ });
1166
+ }
1167
+ /** Creates a task for synchronous work. Thrown values are defects, not typed failures. */
1168
+ static sync(evaluate) {
1169
+ return new ResultTask({
1170
+ _tag: "Sync",
1171
+ evaluate: () => success(evaluate())
1172
+ });
1173
+ }
1174
+ /** Creates a task that maps synchronous throws into the typed error channel. */
1175
+ static try(options) {
1176
+ return new ResultTask({
1177
+ _tag: "Sync",
1178
+ evaluate: () => {
1179
+ try {
1180
+ return success(options.try());
1181
+ } catch (error) {
1182
+ return failed(options.catch(error));
1183
+ }
1184
+ }
1185
+ });
1186
+ }
1187
+ static tryPromise(options) {
1188
+ return new ResultTask(async (context) => {
1189
+ try {
1190
+ return success(await (typeof options === "function" ? options(context.signal) : options.try(context.signal)));
1191
+ } catch (error) {
1192
+ if (context.signal.aborted) return interrupted(context.signal);
1193
+ return failed(typeof options === "function" ? error : options.catch(error));
1194
+ }
1195
+ });
1196
+ }
1197
+ /**
1198
+ * Acquires lazily and registers release in the current scope. Release failures remain in the
1199
+ * scope requirement until `scoped` or a run boundary closes it; catchAll cannot erase them early.
1200
+ */
1201
+ static acquireRelease(options) {
1202
+ return new ResultTask(async (context) => {
1203
+ const acquired = await options.acquire.execute(context);
1204
+ if (acquired._tag === "Failure") return acquired;
1205
+ context.scope.add(async (exit) => {
1206
+ const scope = new TaskScope();
1207
+ const cleanupContext = withScope(context, scope, new AbortController().signal);
1208
+ let released = success(void 0);
1209
+ try {
1210
+ released = await options.release(acquired.value, exit).execute(cleanupContext);
1211
+ } catch (error) {
1212
+ released = died(error);
1213
+ }
1214
+ return scope.close(released);
1215
+ });
1216
+ return acquired;
1217
+ });
1218
+ }
1219
+ /** Closes a child scope before continuing, adding its deferred release errors to E. */
1220
+ static scoped(task) {
1221
+ return new ResultTask(async (context) => {
1222
+ const scope = new TaskScope();
1223
+ const exit = await task.execute(withScope(context, scope));
1224
+ return interruptSuccess(await scope.close(interruptSuccess(exit, context.signal)), context.signal);
1225
+ });
1226
+ }
1227
+ /** Creates a service tag that can be requested with `yield*` inside `ResultTask.gen`. */
1228
+ static service(identifier) {
1229
+ return new ServiceTagValue(identifier);
1230
+ }
1231
+ /** Builds a task from a generator and short-circuits on the first failed task. */
1232
+ static gen(body) {
1233
+ return new ResultTask(async (context) => {
1234
+ try {
1235
+ const iterator = body();
1236
+ const executeTask = async (task) => interruptSuccess(await task.execute(context), context.signal);
1237
+ const closeRuntime = {
1238
+ context,
1239
+ executeTask: (task) => task.execute(withScope(context, context.scope, new AbortController().signal))
1240
+ };
1241
+ let step = iterator.next();
1242
+ while (step.done === false) if (isResultTaskYield(step.value)) {
1243
+ const outcome = await executeTaskSafely(step.value.task, executeTask);
1244
+ if ("error" in outcome) return await closeGenerator(iterator, died(outcome.error), closeRuntime);
1245
+ if (outcome._tag === "Failure") return await closeGenerator(iterator, outcome, closeRuntime);
1246
+ step = iterator.next(outcome);
1247
+ } else if (isServiceYield(step.value)) {
1248
+ const resolution = await resolveService(step.value.tag, context, executeTask);
1249
+ if (resolution._tag === "Found") step = iterator.next(resolution.value);
1250
+ else if (resolution._tag === "Failure") return await closeGenerator(iterator, resolution.exit, closeRuntime);
1251
+ else return await closeGenerator(iterator, died(resolution._tag === "Error" ? resolution.error : new MissingServiceError(step.value.tag.identifier)), closeRuntime);
1252
+ } else if (isErrResult(step.value)) return await closeGenerator(iterator, failed(step.value.error), closeRuntime);
1253
+ else return await closeGenerator(iterator, died(/* @__PURE__ */ new TypeError("ResultTask.gen yielded an unsupported value")), closeRuntime);
1254
+ return success(step.value);
1255
+ } catch (error) {
1256
+ return died(error);
1257
+ }
1258
+ });
1259
+ }
1260
+ /** Maps the success value without executing the task. */
1261
+ map(f) {
1262
+ return new ResultTask({
1263
+ _tag: "Map",
1264
+ task: this,
1265
+ f
1266
+ });
1267
+ }
1268
+ /** Chains another task from the success value without executing either task immediately. */
1269
+ flatMap(f) {
1270
+ return new ResultTask({
1271
+ _tag: "FlatMap",
1272
+ task: this,
1273
+ f
1274
+ });
1275
+ }
1276
+ /** Alias for `flatMap`, matching the existing Resultar vocabulary. */
1277
+ andThen(f) {
1278
+ return this.flatMap(f);
1279
+ }
1280
+ /**
1281
+ * Recovers a single typed failure. Composite causes become a Die(ResultTaskCauseError) so the
1282
+ * removed E cannot escape through runExit; the original tree remains available on error.cause.
1283
+ */
1284
+ catchAll(f) {
1285
+ return new ResultTask({
1286
+ _tag: "CatchAll",
1287
+ task: this,
1288
+ f
1289
+ });
1290
+ }
1291
+ /** Maps the error value without executing the task. */
1292
+ mapError(f) {
1293
+ return new ResultTask({
1294
+ _tag: "MapError",
1295
+ task: this,
1296
+ f
1297
+ });
1298
+ }
1299
+ /**
1300
+ * Executes a side effect on the success value without modifying it.
1301
+ * If the callback returns a `ResultTask`, its requirements and errors are merged.
1302
+ */
1303
+ tap(f) {
1304
+ return new ResultTask({
1305
+ _tag: "Tap",
1306
+ task: this,
1307
+ f
1308
+ });
1309
+ }
1310
+ /**
1311
+ * Executes a side effect on the error value without modifying it.
1312
+ * If the callback returns a `ResultTask`, its requirements and errors are merged.
1313
+ */
1314
+ tapError(f) {
1315
+ return new ResultTask({
1316
+ _tag: "TapError",
1317
+ task: this,
1318
+ f
1319
+ });
1320
+ }
1321
+ /** Replaces the success value with a constant. */
1322
+ as(value) {
1323
+ return this.map(() => value);
1324
+ }
1325
+ /**
1326
+ * Transforms both success and failure cases into a single value type.
1327
+ */
1328
+ match(handlers) {
1329
+ const onSuccess = "onSuccess" in handlers ? handlers.onSuccess : handlers.ok;
1330
+ const onFailure = "onFailure" in handlers ? handlers.onFailure : handlers.err;
1331
+ return this.map(onSuccess).catchAll((error) => ResultTask.succeed(onFailure(error)));
1332
+ }
1333
+ /** Converts this ResultTask into an eagerly started ResultAsync using the standard runtime. */
1334
+ toResultAsync() {
1335
+ return ResultTask.toResultAsync(this);
1336
+ }
1337
+ /** Provides one required service and removes it from the task's requirements. */
1338
+ provideService(tag, ...args) {
1339
+ if (args.length === 0) throw new TypeError("ResultTask.provideService requires a service implementation");
1340
+ return ResultTask.provideService(this, tag, args[0]);
1341
+ }
1342
+ /** Provides all requirements using an object keyed by service identifier. */
1343
+ provideServices(services) {
1344
+ return ResultTask.provideServices(this, services);
1345
+ }
1346
+ /** Provides a lazy resolver for service tags that are not already in the environment. */
1347
+ provideServiceResolver(resolvers) {
1348
+ return ResultTask.provideServiceResolver(this, resolvers);
1349
+ }
1350
+ /** Enables `yield* task` inside `ResultTask.gen` workflows. */
1351
+ *[Symbol.iterator]() {
1352
+ const exit = yield {
1353
+ [ResultTaskYieldTypeId]: ResultTaskYieldTypeId,
1354
+ _tag: "ResultTask",
1355
+ task: this
1356
+ };
1357
+ if (exit._tag === "Success") return exit.value;
1358
+ return throwDefect(/* @__PURE__ */ new Error("ResultTask generator received a failed task result"));
1359
+ }
1360
+ static provideService(...args) {
1361
+ if (args.length >= 3) {
1362
+ const [task, tag, service] = args;
1363
+ if (!isResultTask(task)) throw new TypeError("ResultTask.provideService expects a ResultTask as first argument");
1364
+ if (!isServiceTag(tag)) throw new TypeError("ResultTask.provideService requires a valid service tag");
1365
+ return new ResultTask(async (context) => {
1366
+ const services = new Map([...context.services, [tag.key, service]]);
1367
+ const namedServices = new Map([...context.namedServices, [tag.identifier, service]]);
1368
+ return task.execute(withNamedServices(withServices(context, services), namedServices));
1369
+ });
1370
+ }
1371
+ if (args.length === 2 && !isResultTask(args[0])) {
1372
+ const [tag, service] = args;
1373
+ if (!isServiceTag(tag)) throw new TypeError("ResultTask.provideService requires a valid service tag");
1374
+ return (task) => ResultTask.provideService(task, tag, service);
1375
+ }
1376
+ throw new TypeError("ResultTask.provideService requires a service implementation");
1377
+ }
1378
+ static provideServiceResolver(...args) {
1379
+ if (args.length >= 2) {
1380
+ const [task, resolvers] = args;
1381
+ if (!isResultTask(task)) throw new TypeError("ResultTask.provideServiceResolver expects a ResultTask as first argument");
1382
+ if (!isPlainRecord(resolvers)) throw new TypeError("ResultTask.provideServiceResolver requires a resolvers object");
1383
+ return new ResultTask(async (context) => {
1384
+ const providers = resolvers;
1385
+ return task.execute(withServiceResolver(context, (tag) => Object.hasOwn(providers, tag.identifier) ? providers[tag.identifier]?.() : context.serviceResolver?.(tag)));
1386
+ });
1387
+ }
1388
+ if (!isResultTask(args[0])) {
1389
+ const [resolvers] = args;
1390
+ if (!isPlainRecord(resolvers)) throw new TypeError("ResultTask.provideServiceResolver requires a resolvers object");
1391
+ return (task) => ResultTask.provideServiceResolver(task, resolvers);
1392
+ }
1393
+ throw new TypeError("ResultTask.provideServiceResolver requires a resolvers object");
1394
+ }
1395
+ /** Shares one in-flight execution and successful value. Failed executions can be retried. */
1396
+ static memoize(task) {
1397
+ let pending = void 0;
1398
+ return new ResultTask(async (context) => {
1399
+ pending ??= task.execute(context);
1400
+ const current = pending;
1401
+ const exit = await current;
1402
+ if (exit._tag === "Failure" && pending === current) pending = void 0;
1403
+ return exit;
1404
+ });
1405
+ }
1406
+ /** Creates an explicit resource owner for adapters that manage long-lived scopes. */
1407
+ static makeScope() {
1408
+ const scope = new TaskScope();
1409
+ const controller = new AbortController();
1410
+ const pending = /* @__PURE__ */ new Set();
1411
+ let closing = void 0;
1412
+ return {
1413
+ use: (task) => new ResultTask(async (context) => {
1414
+ if (closing !== void 0) return died(/* @__PURE__ */ new Error("Cannot execute in a closed ResultTask scope"));
1415
+ const attempt = new TaskScope();
1416
+ const execution = task.execute(withScope(context, attempt, controller.signal)).then(async (exit) => {
1417
+ if (exit._tag === "Failure") return attempt.close(exit);
1418
+ scope.adopt(attempt);
1419
+ return exit;
1420
+ });
1421
+ pending.add(execution);
1422
+ execution.then(() => pending.delete(execution));
1423
+ return new Promise((resolve) => {
1424
+ const onAbort = () => {
1425
+ resolve(interrupted(context.signal));
1426
+ };
1427
+ context.signal.addEventListener("abort", onAbort, { once: true });
1428
+ if (context.signal.aborted) onAbort();
1429
+ execution.then((exit) => {
1430
+ context.signal.removeEventListener("abort", onAbort);
1431
+ resolve(interruptSuccess(exit, context.signal));
1432
+ });
1433
+ });
1434
+ }),
1435
+ close: (exit = success(void 0)) => new ResultTask(async () => {
1436
+ closing ??= (async () => {
1437
+ controller.abort("ResultTask scope closed");
1438
+ await Promise.all(pending);
1439
+ return scope.close(exit, true);
1440
+ })();
1441
+ return await closing;
1442
+ })
1443
+ };
1444
+ }
1445
+ static provideServices(...args) {
1446
+ if (args.length >= 2) {
1447
+ const [task, services] = args;
1448
+ if (!isResultTask(task)) throw new TypeError("ResultTask.provideServices expects a ResultTask as first argument");
1449
+ if (!isPlainRecord(services)) throw new TypeError("ResultTask.provideServices requires a services object");
1450
+ return new ResultTask(async (context) => {
1451
+ const namedServices = new Map(context.namedServices);
1452
+ for (const [identifier, service] of Object.entries(services)) namedServices.set(identifier, service);
1453
+ return task.execute(withNamedServices(context, namedServices));
1454
+ });
1455
+ }
1456
+ if (!isResultTask(args[0])) {
1457
+ const [services] = args;
1458
+ if (!isPlainRecord(services)) throw new TypeError("ResultTask.provideServices requires a services object");
1459
+ return (task) => ResultTask.provideServices(task, services);
1460
+ }
1461
+ throw new TypeError("ResultTask.provideServices requires a services object");
1462
+ }
1463
+ static map(taskOrF, f) {
1464
+ if (typeof taskOrF === "function") return (task) => task.map(taskOrF);
1465
+ if (f === void 0) throw new TypeError("ResultTask.map requires a mapping function");
1466
+ return taskOrF.map(f);
1467
+ }
1468
+ static mapError(taskOrF, f) {
1469
+ if (typeof taskOrF === "function") return (task) => task.mapError(taskOrF);
1470
+ if (f === void 0) throw new TypeError("ResultTask.mapError requires an error mapping function");
1471
+ return taskOrF.mapError(f);
1472
+ }
1473
+ static flatMap(taskOrF, f) {
1474
+ if (typeof taskOrF === "function") return (task) => task.flatMap(taskOrF);
1475
+ if (f === void 0) throw new TypeError("ResultTask.flatMap requires a continuation function");
1476
+ return taskOrF.flatMap(f);
1477
+ }
1478
+ static andThen(taskOrF, f) {
1479
+ if (typeof taskOrF === "function") return (task) => task.flatMap(taskOrF);
1480
+ if (f === void 0) throw new TypeError("ResultTask.andThen requires a continuation function");
1481
+ return taskOrF.flatMap(f);
1482
+ }
1483
+ static catchAll(taskOrF, f) {
1484
+ if (typeof taskOrF === "function") return (task) => task.catchAll(taskOrF);
1485
+ if (f === void 0) throw new TypeError("ResultTask.catchAll requires a recovery function");
1486
+ return taskOrF.catchAll(f);
1487
+ }
1488
+ static tap(taskOrF, f) {
1489
+ if (typeof taskOrF === "function") return (task) => task.tap(taskOrF);
1490
+ if (f === void 0) throw new TypeError("ResultTask.tap requires a side-effect function");
1491
+ return taskOrF.tap(f);
1492
+ }
1493
+ static tapError(taskOrF, f) {
1494
+ if (typeof taskOrF === "function") return (task) => task.tapError(taskOrF);
1495
+ if (f === void 0) throw new TypeError("ResultTask.tapError requires an error side-effect function");
1496
+ return taskOrF.tapError(f);
1497
+ }
1498
+ static as(taskOrValue, value) {
1499
+ if (taskOrValue instanceof ResultTask) {
1500
+ if (value === void 0) throw new TypeError("ResultTask.as requires a replacement value");
1501
+ return taskOrValue.as(value);
1502
+ }
1503
+ return (task) => task.as(taskOrValue);
1504
+ }
1505
+ static match(taskOrHandlers, handlers) {
1506
+ if (taskOrHandlers instanceof ResultTask) {
1507
+ if (handlers === void 0) throw new TypeError("ResultTask.match requires match handlers");
1508
+ return taskOrHandlers.match(handlers);
1509
+ }
1510
+ return (task) => task.match(taskOrHandlers);
1511
+ }
1512
+ /**
1513
+ * Eagerly executes a ResultTask using the standard runtime and returns a ResultAsync.
1514
+ */
1515
+ static toResultAsync(task) {
1516
+ return createResultAsync(ResultTask.runResult(task));
1517
+ }
1518
+ /**
1519
+ * Captures an existing ResultAsync or creates a lazy task from a ResultAsync factory.
1520
+ */
1521
+ static fromResultAsync(asyncResultOrFactory) {
1522
+ return new ResultTask(async (context) => {
1523
+ if (context.signal.aborted) return interrupted(context.signal);
1524
+ try {
1525
+ const result = await (typeof asyncResultOrFactory === "function" ? asyncResultOrFactory(context.signal) : asyncResultOrFactory);
1526
+ if (context.signal.aborted) return interrupted(context.signal);
1527
+ return result.isOk() ? success(result.value) : failed(result.error);
1528
+ } catch (error) {
1529
+ return died(error);
1530
+ }
1531
+ });
1532
+ }
1533
+ static async runExitInternal(task, options) {
1534
+ const signal = options?.signal ?? new AbortController().signal;
1535
+ const suppliedServices = options !== void 0 && "services" in options ? options.services : void 0;
1536
+ const namedServices = new Map(Object.entries(suppliedServices ?? {}));
1537
+ const scope = new TaskScope();
1538
+ const context = {
1539
+ namedServices,
1540
+ services: /* @__PURE__ */ new Map(),
1541
+ serviceResolver: void 0,
1542
+ signal,
1543
+ scope
1544
+ };
1545
+ const exit = await task.execute(context);
1546
+ return interruptSuccess(await scope.close(interruptSuccess(exit, signal)), signal);
1547
+ }
1548
+ static async runResultInternal(task, options) {
1549
+ const exit = await ResultTask.runExitInternal(task, options);
1550
+ if (exit._tag === "Success") return ok(exit.value);
1551
+ if (exit.cause._tag === "Fail") return err(exit.cause.error);
1552
+ if (exit.cause._tag === "Die") return throwDefect(exit.cause.defect);
1553
+ if (exit.cause._tag === "Interrupt") throw new AbortError("ResultTask execution interrupted", { cause: exit.cause.reason });
1554
+ throw new ResultTaskCauseError(exit.cause);
1555
+ }
1556
+ static runExit(task, ...args) {
1557
+ return ResultTask.runExitInternal(task, args[0]);
1558
+ }
1559
+ static runResult(task, ...args) {
1560
+ return ResultTask.runResultInternal(task, args[0]);
1561
+ }
1562
+ static async runPromise(task, ...args) {
1563
+ return (await ResultTask.runResultInternal(task, args[0])).unwrapOrThrow();
1564
+ }
1565
+ };
1566
+ //#endregion
676
1567
  //#region src/redacted.ts
677
1568
  const redactedValues = /* @__PURE__ */ new WeakMap();
678
1569
  const formatRedacted = (label) => label === void 0 ? "<redacted>" : `<redacted:${label}>`;
@@ -1532,6 +2423,12 @@ var ResultAsync = class ResultAsync extends Pipeable {
1532
2423
  const newPromise = promise.then((value) => ok(value));
1533
2424
  return new ResultAsync(newPromise);
1534
2425
  }
2426
+ /**
2427
+ * Eagerly executes a ResultTask using the standard runtime and wraps it in a ResultAsync.
2428
+ */
2429
+ static fromTask(task) {
2430
+ return ResultTask.toResultAsync(task);
2431
+ }
1535
2432
  static fromPromise(promise, errorFn) {
1536
2433
  const newPromise = promise.then((value) => ok(value)).catch((error) => err(errorFn(error)));
1537
2434
  return new ResultAsync(newPromise);
@@ -2027,282 +2924,4 @@ const runPromise = (result) => result.unwrapOrThrow();
2027
2924
  /** Compatibility alias. Prefer `tryResultAsync` in new code. */
2028
2925
  const tryCatchAsync = tryResultAsync;
2029
2926
  //#endregion
2030
- //#region src/result-task.ts
2031
- const success = (value) => ({
2032
- _tag: "Success",
2033
- value
2034
- });
2035
- const failure = (cause) => ({
2036
- _tag: "Failure",
2037
- cause
2038
- });
2039
- const failed = (error) => failure({
2040
- _tag: "Fail",
2041
- error
2042
- });
2043
- const died = (defect) => failure({
2044
- _tag: "Die",
2045
- defect
2046
- });
2047
- const throwDefect = (defect) => {
2048
- throw defect;
2049
- };
2050
- const isRecord = (value) => typeof value === "object" && value !== null;
2051
- const createMissingServiceError = (identifier) => {
2052
- const error = /* @__PURE__ */ new Error(`Missing ResultTask service: ${identifier}`);
2053
- error.name = "MissingServiceError";
2054
- return error;
2055
- };
2056
- const isResultTaskYield = (value) => isRecord(value) && value["_tag"] === "ResultTask" && value["task"] instanceof ResultTask;
2057
- const isServiceYield = (value) => isRecord(value) && value["_tag"] === "Service" && value["tag"] instanceof ServiceTagValue;
2058
- const lookupService = (tag, context) => {
2059
- if (context.services.has(tag.key)) return context.services.get(tag.key);
2060
- return context.namedServices.get(tag.identifier);
2061
- };
2062
- const executeTaskSafely = async (task, executeTask) => {
2063
- try {
2064
- return await executeTask(task);
2065
- } catch (error) {
2066
- return { error };
2067
- }
2068
- };
2069
- const closeGenerator = async (iterator, exit, runtime) => {
2070
- try {
2071
- let step = iterator.return(void 0);
2072
- let finalExit = exit;
2073
- while (step.done === false) if (isResultTaskYield(step.value)) {
2074
- const outcome = await executeTaskSafely(step.value.task, runtime.executeTask);
2075
- if ("error" in outcome) {
2076
- finalExit = died(outcome.error);
2077
- step = iterator.return(void 0);
2078
- } else if (outcome._tag === "Failure") {
2079
- finalExit = outcome;
2080
- step = iterator.return(void 0);
2081
- } else step = iterator.next(outcome);
2082
- } else if (isServiceYield(step.value)) {
2083
- const service = lookupService(step.value.tag, runtime.context);
2084
- if (service === void 0) {
2085
- finalExit = died(createMissingServiceError(step.value.tag.identifier));
2086
- step = iterator.return(void 0);
2087
- } else step = iterator.next(service);
2088
- } else {
2089
- finalExit = died(/* @__PURE__ */ new TypeError("ResultTask.gen yielded an unsupported value"));
2090
- step = iterator.return(void 0);
2091
- }
2092
- return finalExit;
2093
- } catch (error) {
2094
- return died(error);
2095
- }
2096
- };
2097
- const withServices = (context, services) => ({
2098
- namedServices: context.namedServices,
2099
- services,
2100
- signal: context.signal
2101
- });
2102
- const withNamedServices = (context, namedServices) => ({
2103
- namedServices,
2104
- services: context.services,
2105
- signal: context.signal
2106
- });
2107
- var ServiceTagValue = class {
2108
- _tag = "ServiceTag";
2109
- identifier;
2110
- key;
2111
- constructor(identifier) {
2112
- this.identifier = identifier;
2113
- this.key = Symbol(identifier);
2114
- }
2115
- *[Symbol.iterator]() {
2116
- return yield {
2117
- _tag: "Service",
2118
- tag: this
2119
- };
2120
- }
2121
- };
2122
- /**
2123
- * A lazy, composable workflow that can succeed with `A` or fail with `E`.
2124
- *
2125
- * Constructing a `ResultTask` never runs its work. Use `runResult`, `runExit`, or `runPromise` at an
2126
- * explicit application boundary to execute it.
2127
- */
2128
- var ResultTask = class ResultTask extends Pipeable {
2129
- execute;
2130
- constructor(execute) {
2131
- super();
2132
- this.execute = execute;
2133
- }
2134
- /** Creates a task that succeeds with `value` when it is executed. */
2135
- static succeed(value) {
2136
- return new ResultTask(() => Promise.resolve(success(value)));
2137
- }
2138
- /** Creates a task that fails with `error` when it is executed. */
2139
- static fail(error) {
2140
- return new ResultTask(() => Promise.resolve(failed(error)));
2141
- }
2142
- /** Lifts an already computed Result into a lazy task. */
2143
- static fromResult(result) {
2144
- return new ResultTask(() => Promise.resolve(result.isOk() ? success(result.value) : failed(result.error)));
2145
- }
2146
- /** Creates a task for synchronous work. Thrown values are defects, not typed failures. */
2147
- static sync(evaluate) {
2148
- return new ResultTask(() => Promise.resolve(success(evaluate())));
2149
- }
2150
- /** Creates a task that maps synchronous throws into the typed error channel. */
2151
- static try(options) {
2152
- return new ResultTask(() => {
2153
- try {
2154
- return Promise.resolve(success(options.try()));
2155
- } catch (error) {
2156
- return Promise.resolve(failed(options.catch(error)));
2157
- }
2158
- });
2159
- }
2160
- /** Creates a lazy task that maps synchronous throws and promise rejections into `E`. */
2161
- static tryPromise(options) {
2162
- return new ResultTask(async (context) => {
2163
- try {
2164
- return success(await options.try(context.signal));
2165
- } catch (error) {
2166
- return failed(options.catch(error));
2167
- }
2168
- });
2169
- }
2170
- /** Creates a service tag that can be requested with `yield*` inside `ResultTask.gen`. */
2171
- static service(identifier) {
2172
- return new ServiceTagValue(identifier);
2173
- }
2174
- /** Builds a task from a generator and short-circuits on the first failed task. */
2175
- static gen(body) {
2176
- return new ResultTask(async (context) => {
2177
- try {
2178
- const iterator = body();
2179
- const executeTask = (task) => task.execute(context);
2180
- let step = iterator.next();
2181
- while (step.done === false) if (isResultTaskYield(step.value)) {
2182
- const outcome = await executeTaskSafely(step.value.task, executeTask);
2183
- if ("error" in outcome) return await closeGenerator(iterator, died(outcome.error), {
2184
- context,
2185
- executeTask
2186
- });
2187
- if (outcome._tag === "Failure") return await closeGenerator(iterator, outcome, {
2188
- context,
2189
- executeTask
2190
- });
2191
- step = iterator.next(outcome);
2192
- } else if (isServiceYield(step.value)) {
2193
- const service = lookupService(step.value.tag, context);
2194
- if (service === void 0) return await closeGenerator(iterator, died(createMissingServiceError(step.value.tag.identifier)), {
2195
- context,
2196
- executeTask
2197
- });
2198
- step = iterator.next(service);
2199
- } else return await closeGenerator(iterator, died(/* @__PURE__ */ new TypeError("ResultTask.gen yielded an unsupported value")), {
2200
- context,
2201
- executeTask
2202
- });
2203
- return success(step.value);
2204
- } catch (error) {
2205
- return died(error);
2206
- }
2207
- });
2208
- }
2209
- /** Maps the success value without executing the task. */
2210
- map(f) {
2211
- return new ResultTask(async (context) => {
2212
- const exit = await this.execute(context);
2213
- if (exit._tag === "Failure") return exit;
2214
- return success(f(exit.value));
2215
- });
2216
- }
2217
- /** Chains another task from the success value without executing either task immediately. */
2218
- flatMap(f) {
2219
- return new ResultTask(async (context) => {
2220
- const exit = await this.execute(context);
2221
- if (exit._tag === "Failure") return exit;
2222
- return f(exit.value).execute(context);
2223
- });
2224
- }
2225
- /** Alias for `flatMap`, matching the existing Resultar vocabulary. */
2226
- andThen(f) {
2227
- return this.flatMap(f);
2228
- }
2229
- /** Recovers from a typed failure without recovering from a runtime defect. */
2230
- catchAll(f) {
2231
- return new ResultTask(async (context) => {
2232
- const exit = await this.execute(context);
2233
- if (exit._tag === "Success") return exit;
2234
- if (exit.cause._tag === "Die") return exit;
2235
- return f(exit.cause.error).execute(context);
2236
- });
2237
- }
2238
- /** Enables `yield* task` inside `ResultTask.gen` workflows. */
2239
- *[Symbol.iterator]() {
2240
- const exit = yield {
2241
- _tag: "ResultTask",
2242
- task: this
2243
- };
2244
- if (exit._tag === "Success") return exit.value;
2245
- return throwDefect(/* @__PURE__ */ new Error("ResultTask generator received a failed task result"));
2246
- }
2247
- /** Provides one required service and removes it from the task's requirements. */
2248
- static provideService(task, tag, service) {
2249
- return new ResultTask(async (context) => {
2250
- const services = new Map([...context.services, [tag.key, service]]);
2251
- return task.execute(withServices(context, services));
2252
- });
2253
- }
2254
- /** Provides all requirements using an object keyed by service identifier. */
2255
- static provideServices(task, services) {
2256
- return new ResultTask(async (context) => {
2257
- const namedServices = new Map(context.namedServices);
2258
- for (const [identifier, service] of Object.entries(services)) namedServices.set(identifier, service);
2259
- return task.execute(withNamedServices(context, namedServices));
2260
- });
2261
- }
2262
- /** Maps the success value using the canonical functional form. */
2263
- static map(task, f) {
2264
- return task.map(f);
2265
- }
2266
- /** Chains a task using the canonical functional form. */
2267
- static flatMap(task, f) {
2268
- return task.flatMap(f);
2269
- }
2270
- /** Recovers from a typed failure using the canonical functional form. */
2271
- static catchAll(task, f) {
2272
- return task.catchAll(f);
2273
- }
2274
- static async runExitInternal(task, options) {
2275
- const signal = options?.signal ?? new AbortController().signal;
2276
- const suppliedServices = options !== void 0 && "services" in options ? options.services : void 0;
2277
- const context = {
2278
- namedServices: new Map(Object.entries(suppliedServices ?? {})),
2279
- services: /* @__PURE__ */ new Map(),
2280
- signal
2281
- };
2282
- try {
2283
- return await task.execute(context);
2284
- } catch (error) {
2285
- return died(error);
2286
- }
2287
- }
2288
- static async runResultInternal(task, options) {
2289
- const exit = await ResultTask.runExitInternal(task, options);
2290
- if (exit._tag === "Success") return ok(exit.value);
2291
- if (exit.cause._tag === "Fail") return err(exit.cause.error);
2292
- return throwDefect(exit.cause.defect);
2293
- }
2294
- /** Runs a task and preserves success, typed failure, and runtime defects in an `Exit`. */
2295
- static runExit(task, ...args) {
2296
- return ResultTask.runExitInternal(task, args[0]);
2297
- }
2298
- /** Runs a task and returns a Result, rejecting only when a runtime defect occurs. */
2299
- static runResult(task, ...args) {
2300
- return ResultTask.runResultInternal(task, args[0]);
2301
- }
2302
- /** Runs a task and returns the success value, rejecting on typed failures or defects. */
2303
- static async runPromise(task, ...args) {
2304
- return (await ResultTask.runResultInternal(task, args[0])).unwrapOrThrow();
2305
- }
2306
- };
2307
- //#endregion
2308
- export { AbortError, DisposableResult, DisposableResultAsync, Result, ResultAsync, ResultTask, createTaggedError, tryResult as default, tryResult as try, tryResult, err, errAsync, findCause, fromCallback, fromPromise, fromSafePromise, fromThrowable, fromThrowableAsync, isAbortError, isError, isRedacted, matchError, matchErrorPartial, ok, okAsync, redact, revealRedacted, runPromise, runSync, safeTry, taggedEnum, tryResultAsync as tryAsync, tryResultAsync, tryCatch, tryCatchAsync, unit, unitAsync };
2927
+ export { AbortError, DisposableResult, DisposableResultAsync, MissingServiceError, Result, ResultAsync, ResultTask, ResultTaskCauseError, ResultTaskTypeId, ResultTaskYieldTypeId, ServiceTagTypeId, createTaggedError, tryResult as default, tryResult as try, tryResult, err, errAsync, findCause, fromCallback, fromPromise, fromSafePromise, fromThrowable, fromThrowableAsync, isAbortError, isError, isRedacted, isResultTask, isServiceTag, matchError, matchErrorPartial, ok, okAsync, redact, revealRedacted, runPromise, runSync, safeTry, serviceTag, taggedEnum, tryResultAsync as tryAsync, tryResultAsync, tryCatch, tryCatchAsync, unit, unitAsync };