@effect/workflow
Advanced tools
Comparing version
@@ -205,3 +205,8 @@ "use strict"; | ||
exports.Complete = Complete; | ||
class Suspended extends /*#__PURE__*/Schema.TaggedClass("@effect/workflow/Workflow/Suspended")("Suspended", {}) { | ||
class Suspended extends /*#__PURE__*/Schema.TaggedClass("@effect/workflow/Workflow/Suspended")("Suspended", { | ||
cause: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Cause({ | ||
error: Schema.Never, | ||
defect: Schema.Defect | ||
})) | ||
}) { | ||
/** | ||
@@ -227,4 +232,7 @@ * @since 1.0.0 | ||
const suspendOnFailure = Context.get(instance.workflow.annotations, SuspendOnFailure); | ||
return Effect.uninterruptibleMask(restore => restore(effect).pipe(suspendOnFailure ? Effect.catchAllCause(() => { | ||
return Effect.uninterruptibleMask(restore => restore(effect).pipe(suspendOnFailure ? Effect.catchAllCause(cause => { | ||
instance.suspended = true; | ||
if (!Cause.isInterruptedOnly(cause)) { | ||
instance.cause = Cause.die(Cause.squash(cause)); | ||
} | ||
return Effect.interrupt; | ||
@@ -235,3 +243,5 @@ }) : _Function.identity, Effect.scoped, Effect.matchCauseEffect({ | ||
})), | ||
onFailure: cause => instance.suspended ? Effect.succeed(new Suspended()) : !instance.interrupted && Cause.isInterruptedOnly(cause) || !captureDefects && Cause.isDie(cause) ? Effect.failCause(cause) : Effect.succeed(new Complete({ | ||
onFailure: cause => instance.suspended ? Effect.succeed(new Suspended({ | ||
cause: instance.cause | ||
})) : !instance.interrupted && Cause.isInterruptedOnly(cause) || !captureDefects && Cause.isDie(cause) ? Effect.failCause(cause) : Effect.succeed(new Complete({ | ||
exit: Exit.failCause(cause) | ||
@@ -257,2 +267,5 @@ })) | ||
const isSuspended = Exit.isSuccess(exit) && isSuspend(exit.value); | ||
if (Exit.isSuccess(exit) && isResult(exit.value) && exit.value._tag === "Suspended" && exit.value.cause) { | ||
instance.cause = instance.cause ? Cause.sequential(instance.cause, exit.value.cause) : exit.value.cause; | ||
} | ||
return state.count === 0 ? state.latch.open : isSuspended ? state.latch.await : Effect.void; | ||
@@ -259,0 +272,0 @@ }); |
@@ -12,6 +12,2 @@ "use strict"; | ||
* @since 1.0.0 | ||
*/ | ||
/** | ||
* @since 1.0.0 | ||
* @category Services | ||
@@ -32,2 +28,3 @@ */ | ||
interrupted: false, | ||
cause: undefined, | ||
activityState: { | ||
@@ -34,0 +31,0 @@ count: 0, |
@@ -11,2 +11,3 @@ "use strict"; | ||
var RpcGroup = _interopRequireWildcard(require("@effect/rpc/RpcGroup")); | ||
var Schema = _interopRequireWildcard(require("effect/Schema")); | ||
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } | ||
@@ -60,2 +61,4 @@ /** | ||
payload: workflow.payloadSchema | ||
}).annotateContext(workflow.annotations), Rpc.make(`${prefix}${workflow.name}Resume`, { | ||
payload: ResumePayload | ||
}).annotateContext(workflow.annotations)); | ||
@@ -105,3 +108,3 @@ } | ||
const path = `/${tagToPath(workflow.name)}`; | ||
group = group.add(HttpApiEndpoint.post(workflow.name, path).setPayload(workflow.payloadSchema).addSuccess(workflow.successSchema).addError(workflow.errorSchema).annotateContext(workflow.annotations)).add(HttpApiEndpoint.post(workflow.name + "Discard", `${path}/discard`).setPayload(workflow.payloadSchema).annotateContext(workflow.annotations)); | ||
group = group.add(HttpApiEndpoint.post(workflow.name, path).setPayload(workflow.payloadSchema).addSuccess(workflow.successSchema).addError(workflow.errorSchema).annotateContext(workflow.annotations)).add(HttpApiEndpoint.post(workflow.name + "Discard", `${path}/discard`).setPayload(workflow.payloadSchema).annotateContext(workflow.annotations)).add(HttpApiEndpoint.post(workflow.name + "Resume", `${path}/resume`).setPayload(ResumePayload).annotateContext(workflow.annotations)); | ||
} | ||
@@ -114,2 +117,5 @@ return group; | ||
.toLowerCase(); | ||
const ResumePayload = /*#__PURE__*/Schema.Struct({ | ||
executionId: Schema.String | ||
}); | ||
//# sourceMappingURL=WorkflowProxy.js.map |
@@ -26,3 +26,5 @@ "use strict"; | ||
discard: true | ||
})); | ||
})).handle(workflow.name + "Resume", ({ | ||
payload | ||
}) => workflow.resume(payload.executionId)); | ||
} | ||
@@ -44,4 +46,6 @@ return handlers; | ||
const tagDiscard = `${tag}Discard`; | ||
const tagResume = `${tag}Resume`; | ||
const key = `@effect/rpc/Rpc/${tag}`; | ||
const keyDiscard = `${key}Discard`; | ||
const keyResume = `${key}Resume`; | ||
handlers.set(key, { | ||
@@ -59,2 +63,7 @@ context, | ||
}); | ||
handlers.set(keyResume, { | ||
context, | ||
tag: tagResume, | ||
handler: payload => workflow.resume(payload.executionId) | ||
}); | ||
} | ||
@@ -61,0 +70,0 @@ return Context.unsafeMake(handlers); |
@@ -224,2 +224,4 @@ /** | ||
readonly _tag: Schema.tag<"Suspended">; | ||
} & { | ||
cause: Schema.optional<Schema.Cause<typeof Schema.Never, typeof Schema.Defect>>; | ||
}>; | ||
@@ -226,0 +228,0 @@ /** |
/** | ||
* @since 1.0.0 | ||
*/ | ||
import type * as Cause from "effect/Cause"; | ||
import * as Context from "effect/Context"; | ||
@@ -88,2 +89,7 @@ import * as Effect from "effect/Effect"; | ||
interrupted: boolean; | ||
/** | ||
* When SuspendOnFailure is triggered, the cause of the failure is stored | ||
* here. | ||
*/ | ||
cause: Cause.Cause<never> | undefined; | ||
readonly activityState: { | ||
@@ -90,0 +96,0 @@ count: number; |
@@ -9,2 +9,3 @@ /** | ||
import type { NonEmptyReadonlyArray } from "effect/Array"; | ||
import * as Schema from "effect/Schema"; | ||
import type * as Workflow from "./Workflow.js"; | ||
@@ -50,3 +51,3 @@ /** | ||
*/ | ||
export type ConvertRpcs<Workflows extends Workflow.Any, Prefix extends string> = Workflows extends Workflow.Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? Rpc.Rpc<`${Prefix}${_Name}`, _Payload, _Success, _Error> | Rpc.Rpc<`${Prefix}${_Name}Discard`, _Payload> : never; | ||
export type ConvertRpcs<Workflows extends Workflow.Any, Prefix extends string> = Workflows extends Workflow.Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? Rpc.Rpc<`${Prefix}${_Name}`, _Payload, _Success, _Error> | Rpc.Rpc<`${Prefix}${_Name}Discard`, _Payload> | Rpc.Rpc<`${Prefix}${_Name}Resume`, typeof ResumePayload> : never; | ||
/** | ||
@@ -91,3 +92,7 @@ * Derives an `HttpApiGroup` from a list of workflows. | ||
*/ | ||
export type ConvertHttpApi<Workflows extends Workflow.Any> = Workflows extends Workflow.Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? HttpApiEndpoint.HttpApiEndpoint<_Name, "POST", never, never, _Payload["Type"], never, _Success["Type"], _Error["Type"], _Payload["Context"] | _Success["Context"], _Error["Context"]> | HttpApiEndpoint.HttpApiEndpoint<`${_Name}Discard`, "POST", never, never, _Payload["Type"], never, void, never, _Payload["Context"]> : never; | ||
export type ConvertHttpApi<Workflows extends Workflow.Any> = Workflows extends Workflow.Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? HttpApiEndpoint.HttpApiEndpoint<_Name, "POST", never, never, _Payload["Type"], never, _Success["Type"], _Error["Type"], _Payload["Context"] | _Success["Context"], _Error["Context"]> | HttpApiEndpoint.HttpApiEndpoint<`${_Name}Discard`, "POST", never, never, _Payload["Type"], never, void, never, _Payload["Context"]> | HttpApiEndpoint.HttpApiEndpoint<`${_Name}Resume`, "POST", never, never, typeof ResumePayload.Type, never, void, never, typeof ResumePayload.Context> : never; | ||
declare const ResumePayload: Schema.Struct<{ | ||
executionId: typeof Schema.String; | ||
}>; | ||
export {}; | ||
//# sourceMappingURL=WorkflowProxy.d.ts.map |
@@ -26,3 +26,3 @@ /** | ||
*/ | ||
export type RpcHandlers<Workflows extends Workflow.Any, Prefix extends string> = Workflows extends Workflow.Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? Rpc.Handler<`${Prefix}${_Name}`> | Rpc.Handler<`${Prefix}${_Name}Discard`> : never; | ||
export type RpcHandlers<Workflows extends Workflow.Any, Prefix extends string> = Workflows extends Workflow.Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? Rpc.Handler<`${Prefix}${_Name}`> | Rpc.Handler<`${Prefix}${_Name}Discard`> | Rpc.Handler<`${Prefix}${_Name}Resume`> : never; | ||
//# sourceMappingURL=WorkflowProxyServer.d.ts.map |
@@ -193,3 +193,8 @@ /** | ||
*/ | ||
export class Suspended extends /*#__PURE__*/Schema.TaggedClass("@effect/workflow/Workflow/Suspended")("Suspended", {}) { | ||
export class Suspended extends /*#__PURE__*/Schema.TaggedClass("@effect/workflow/Workflow/Suspended")("Suspended", { | ||
cause: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Cause({ | ||
error: Schema.Never, | ||
defect: Schema.Defect | ||
})) | ||
}) { | ||
/** | ||
@@ -213,4 +218,7 @@ * @since 1.0.0 | ||
const suspendOnFailure = Context.get(instance.workflow.annotations, SuspendOnFailure); | ||
return Effect.uninterruptibleMask(restore => restore(effect).pipe(suspendOnFailure ? Effect.catchAllCause(() => { | ||
return Effect.uninterruptibleMask(restore => restore(effect).pipe(suspendOnFailure ? Effect.catchAllCause(cause => { | ||
instance.suspended = true; | ||
if (!Cause.isInterruptedOnly(cause)) { | ||
instance.cause = Cause.die(Cause.squash(cause)); | ||
} | ||
return Effect.interrupt; | ||
@@ -221,3 +229,5 @@ }) : identity, Effect.scoped, Effect.matchCauseEffect({ | ||
})), | ||
onFailure: cause => instance.suspended ? Effect.succeed(new Suspended()) : !instance.interrupted && Cause.isInterruptedOnly(cause) || !captureDefects && Cause.isDie(cause) ? Effect.failCause(cause) : Effect.succeed(new Complete({ | ||
onFailure: cause => instance.suspended ? Effect.succeed(new Suspended({ | ||
cause: instance.cause | ||
})) : !instance.interrupted && Cause.isInterruptedOnly(cause) || !captureDefects && Cause.isDie(cause) ? Effect.failCause(cause) : Effect.succeed(new Complete({ | ||
exit: Exit.failCause(cause) | ||
@@ -242,2 +252,5 @@ })) | ||
const isSuspended = Exit.isSuccess(exit) && isSuspend(exit.value); | ||
if (Exit.isSuccess(exit) && isResult(exit.value) && exit.value._tag === "Suspended" && exit.value.cause) { | ||
instance.cause = instance.cause ? Cause.sequential(instance.cause, exit.value.cause) : exit.value.cause; | ||
} | ||
return state.count === 0 ? state.latch.open : isSuspended ? state.latch.await : Effect.void; | ||
@@ -244,0 +257,0 @@ }); |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
import * as Context from "effect/Context"; | ||
@@ -22,2 +19,3 @@ import * as Effect from "effect/Effect"; | ||
interrupted: false, | ||
cause: undefined, | ||
activityState: { | ||
@@ -24,0 +22,0 @@ count: 0, |
@@ -8,2 +8,3 @@ /** | ||
import * as RpcGroup from "@effect/rpc/RpcGroup"; | ||
import * as Schema from "effect/Schema"; | ||
/** | ||
@@ -52,2 +53,4 @@ * Derives an `RpcGroup` from a list of workflows. | ||
payload: workflow.payloadSchema | ||
}).annotateContext(workflow.annotations), Rpc.make(`${prefix}${workflow.name}Resume`, { | ||
payload: ResumePayload | ||
}).annotateContext(workflow.annotations)); | ||
@@ -96,3 +99,3 @@ } | ||
const path = `/${tagToPath(workflow.name)}`; | ||
group = group.add(HttpApiEndpoint.post(workflow.name, path).setPayload(workflow.payloadSchema).addSuccess(workflow.successSchema).addError(workflow.errorSchema).annotateContext(workflow.annotations)).add(HttpApiEndpoint.post(workflow.name + "Discard", `${path}/discard`).setPayload(workflow.payloadSchema).annotateContext(workflow.annotations)); | ||
group = group.add(HttpApiEndpoint.post(workflow.name, path).setPayload(workflow.payloadSchema).addSuccess(workflow.successSchema).addError(workflow.errorSchema).annotateContext(workflow.annotations)).add(HttpApiEndpoint.post(workflow.name + "Discard", `${path}/discard`).setPayload(workflow.payloadSchema).annotateContext(workflow.annotations)).add(HttpApiEndpoint.post(workflow.name + "Resume", `${path}/resume`).setPayload(ResumePayload).annotateContext(workflow.annotations)); | ||
} | ||
@@ -104,2 +107,5 @@ return group; | ||
.toLowerCase(); | ||
const ResumePayload = /*#__PURE__*/Schema.Struct({ | ||
executionId: Schema.String | ||
}); | ||
//# sourceMappingURL=WorkflowProxy.js.map |
@@ -19,3 +19,5 @@ import * as HttpApiBuilder from "@effect/platform/HttpApiBuilder"; | ||
discard: true | ||
})); | ||
})).handle(workflow.name + "Resume", ({ | ||
payload | ||
}) => workflow.resume(payload.executionId)); | ||
} | ||
@@ -36,4 +38,6 @@ return handlers; | ||
const tagDiscard = `${tag}Discard`; | ||
const tagResume = `${tag}Resume`; | ||
const key = `@effect/rpc/Rpc/${tag}`; | ||
const keyDiscard = `${key}Discard`; | ||
const keyResume = `${key}Resume`; | ||
handlers.set(key, { | ||
@@ -51,2 +55,7 @@ context, | ||
}); | ||
handlers.set(keyResume, { | ||
context, | ||
tag: tagResume, | ||
handler: payload => workflow.resume(payload.executionId) | ||
}); | ||
} | ||
@@ -53,0 +62,0 @@ return Context.unsafeMake(handlers); |
{ | ||
"name": "@effect/workflow", | ||
"version": "0.8.0", | ||
"version": "0.8.1", | ||
"description": "Durable workflows for Effect", | ||
@@ -15,4 +15,4 @@ "license": "MIT", | ||
"effect": "^3.17.1", | ||
"@effect/platform": "^0.90.0", | ||
"@effect/rpc": "^0.68.0" | ||
"@effect/rpc": "^0.68.0", | ||
"@effect/platform": "^0.90.0" | ||
}, | ||
@@ -19,0 +19,0 @@ "publishConfig": { |
@@ -462,3 +462,5 @@ /** | ||
*/ | ||
export class Suspended extends Schema.TaggedClass<Suspended>("@effect/workflow/Workflow/Suspended")("Suspended", {}) { | ||
export class Suspended extends Schema.TaggedClass<Suspended>("@effect/workflow/Workflow/Suspended")("Suspended", { | ||
cause: Schema.optional(Schema.Cause({ error: Schema.Never, defect: Schema.Defect })) | ||
}) { | ||
/** | ||
@@ -499,4 +501,7 @@ * @since 1.0.0 | ||
suspendOnFailure ? | ||
Effect.catchAllCause(() => { | ||
Effect.catchAllCause((cause) => { | ||
instance.suspended = true | ||
if (!Cause.isInterruptedOnly(cause)) { | ||
instance.cause = Cause.die(Cause.squash(cause)) | ||
} | ||
return Effect.interrupt | ||
@@ -510,3 +515,3 @@ }) : | ||
instance.suspended | ||
? Effect.succeed(new Suspended()) | ||
? Effect.succeed(new Suspended({ cause: instance.cause })) | ||
: (!instance.interrupted && Cause.isInterruptedOnly(cause)) || (!captureDefects && Cause.isDie(cause)) | ||
@@ -544,2 +549,5 @@ ? Effect.failCause(cause as Cause.Cause<never>) | ||
const isSuspended = Exit.isSuccess(exit) && isSuspend(exit.value) | ||
if (Exit.isSuccess(exit) && isResult(exit.value) && exit.value._tag === "Suspended" && exit.value.cause) { | ||
instance.cause = instance.cause ? Cause.sequential(instance.cause, exit.value.cause) : exit.value.cause | ||
} | ||
return state.count === 0 ? state.latch.open : isSuspended ? state.latch.await : Effect.void | ||
@@ -546,0 +554,0 @@ }) |
/** | ||
* @since 1.0.0 | ||
*/ | ||
import type * as Cause from "effect/Cause" | ||
import * as Context from "effect/Context" | ||
@@ -128,2 +129,8 @@ import * as Effect from "effect/Effect" | ||
/** | ||
* When SuspendOnFailure is triggered, the cause of the failure is stored | ||
* here. | ||
*/ | ||
cause: Cause.Cause<never> | undefined | ||
readonly activityState: { | ||
@@ -141,2 +148,3 @@ count: number | ||
interrupted: false, | ||
cause: undefined, | ||
activityState: { | ||
@@ -143,0 +151,0 @@ count: 0, |
@@ -9,2 +9,3 @@ /** | ||
import type { NonEmptyReadonlyArray } from "effect/Array" | ||
import * as Schema from "effect/Schema" | ||
import type * as Workflow from "./Workflow.js" | ||
@@ -65,3 +66,5 @@ | ||
payload: workflow.payloadSchema | ||
}).annotateContext(workflow.annotations) | ||
}).annotateContext(workflow.annotations), | ||
Rpc.make(`${prefix}${workflow.name}Resume`, { payload: ResumePayload }) | ||
.annotateContext(workflow.annotations) | ||
) | ||
@@ -83,2 +86,3 @@ } | ||
| Rpc.Rpc<`${Prefix}${_Name}Discard`, _Payload> | ||
| Rpc.Rpc<`${Prefix}${_Name}Resume`, typeof ResumePayload> | ||
: never | ||
@@ -138,2 +142,6 @@ | ||
.annotateContext(workflow.annotations) | ||
).add( | ||
HttpApiEndpoint.post(workflow.name + "Resume", `${path}/resume`) | ||
.setPayload(ResumePayload) | ||
.annotateContext(workflow.annotations) | ||
) as any | ||
@@ -181,3 +189,16 @@ } | ||
_Payload["Context"] | ||
> | ||
| HttpApiEndpoint.HttpApiEndpoint< | ||
`${_Name}Resume`, | ||
"POST", | ||
never, | ||
never, | ||
typeof ResumePayload.Type, | ||
never, | ||
void, | ||
never, | ||
typeof ResumePayload.Context | ||
> : | ||
never | ||
const ResumePayload = Schema.Struct({ executionId: Schema.String }) |
@@ -51,2 +51,6 @@ /** | ||
) | ||
.handle( | ||
workflow.name + "Resume" as any, | ||
({ payload }: { payload: any }) => workflow.resume(payload.executionId) | ||
) | ||
} | ||
@@ -79,4 +83,6 @@ return handlers as HttpApiBuilder.Handlers<never, never, never> | ||
const tagDiscard = `${tag}Discard` | ||
const tagResume = `${tag}Resume` | ||
const key = `@effect/rpc/Rpc/${tag}` | ||
const keyDiscard = `${key}Discard` | ||
const keyResume = `${key}Resume` | ||
handlers.set(key, { | ||
@@ -92,2 +98,7 @@ context, | ||
} as any) | ||
handlers.set(keyResume, { | ||
context, | ||
tag: tagResume, | ||
handler: (payload: any) => workflow.resume(payload.executionId) as any | ||
} as any) | ||
} | ||
@@ -105,3 +116,3 @@ return Context.unsafeMake(handlers) | ||
infer _Error | ||
> ? Rpc.Handler<`${Prefix}${_Name}`> | Rpc.Handler<`${Prefix}${_Name}Discard`> | ||
> ? Rpc.Handler<`${Prefix}${_Name}`> | Rpc.Handler<`${Prefix}${_Name}Discard`> | Rpc.Handler<`${Prefix}${_Name}Resume`> | ||
: never |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
273824
3.28%4654
2.49%