@smthrs/flow 1.0.0-rc.8 → 1.0.0-rc.9
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/cjs/Deadline.d.ts +5 -0
- package/dist/cjs/Deadline.d.ts.map +1 -1
- package/dist/cjs/Deadline.js +9 -1
- package/dist/cjs/Deadline.js.map +2 -2
- package/dist/cjs/DurableClock.d.ts +9 -10
- package/dist/cjs/DurableClock.d.ts.map +1 -1
- package/dist/cjs/DurableClock.js +19 -2
- package/dist/cjs/DurableClock.js.map +2 -2
- package/dist/cjs/Flow/make.d.ts +2 -1
- package/dist/cjs/Flow/make.d.ts.map +1 -1
- package/dist/cjs/Flow/make.js +3 -0
- package/dist/cjs/Flow/make.js.map +2 -2
- package/dist/cjs/HumanTask.d.ts.map +1 -1
- package/dist/cjs/HumanTask.js +2 -2
- package/dist/cjs/HumanTask.js.map +2 -2
- package/dist/esm/Deadline.d.ts +5 -0
- package/dist/esm/Deadline.d.ts.map +1 -1
- package/dist/esm/Deadline.js +13 -1
- package/dist/esm/Deadline.js.map +1 -1
- package/dist/esm/DurableClock.d.ts +9 -10
- package/dist/esm/DurableClock.d.ts.map +1 -1
- package/dist/esm/DurableClock.js +49 -2
- package/dist/esm/DurableClock.js.map +1 -1
- package/dist/esm/Flow/make.d.ts +2 -1
- package/dist/esm/Flow/make.d.ts.map +1 -1
- package/dist/esm/Flow/make.js +5 -0
- package/dist/esm/Flow/make.js.map +1 -1
- package/dist/esm/HumanTask.d.ts.map +1 -1
- package/dist/esm/HumanTask.js +5 -3
- package/dist/esm/HumanTask.js.map +1 -1
- package/docs/api.md +15 -11
- package/docs/guides/ask-a-person.md +5 -5
- package/docs/guides/inspect-the-plan.md +1 -1
- package/docs/reference/flow.md +4 -4
- package/package.json +7 -7
- package/src/Deadline.ts +17 -1
- package/src/DurableClock.ts +45 -2
- package/src/Flow/make.ts +7 -1
- package/src/HumanTask.ts +5 -3
package/src/DurableClock.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* @since 0.1.0
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import * as Clock from "effect/Clock"
|
|
14
15
|
import type * as Crypto from "effect/Crypto"
|
|
15
16
|
import * as Duration from "effect/Duration"
|
|
16
17
|
import * as Effect from "effect/Effect"
|
|
@@ -56,6 +57,28 @@ const durationFromInput = (input: Duration.Input, field: string): Duration.Durat
|
|
|
56
57
|
return parsed.value
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
/**
|
|
61
|
+
* The latest due time a durable timer records, in epoch milliseconds: a store
|
|
62
|
+
* keeps a clock's due time as a safe integer.
|
|
63
|
+
*
|
|
64
|
+
* @private
|
|
65
|
+
*/
|
|
66
|
+
const latestDueAtMs = Number.MAX_SAFE_INTEGER
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Parses a clock's own duration, which a store adds to the current time and
|
|
70
|
+
* records, so it is at most {@link latestDueAtMs} milliseconds.
|
|
71
|
+
*
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
const clockDuration = (input: Duration.Input): Duration.Duration => {
|
|
75
|
+
const duration = durationFromInput(input, "duration")
|
|
76
|
+
if (Duration.toMillis(duration) > latestDueAtMs) {
|
|
77
|
+
throw new RangeError(`DurableClock: "duration" must be at most ${latestDueAtMs} milliseconds.`)
|
|
78
|
+
}
|
|
79
|
+
return duration
|
|
80
|
+
}
|
|
81
|
+
|
|
59
82
|
const makeClock = (name: string, duration: Duration.Duration): DurableClock => ({
|
|
60
83
|
[TypeId]: TypeId,
|
|
61
84
|
name,
|
|
@@ -66,18 +89,27 @@ const makeClock = (name: string, duration: Duration.Duration): DurableClock => (
|
|
|
66
89
|
/**
|
|
67
90
|
* Declares one durable clock after validating its finite nonnegative duration.
|
|
68
91
|
*
|
|
92
|
+
* Throws a `RangeError` for a malformed, infinite or negative duration, or one
|
|
93
|
+
* longer than `Number.MAX_SAFE_INTEGER` milliseconds: a durable store records
|
|
94
|
+
* a clock's due time as a safe integer.
|
|
95
|
+
*
|
|
69
96
|
* @category constructors
|
|
70
97
|
* @since 0.1.0
|
|
71
98
|
*/
|
|
72
99
|
export const make = (options: {
|
|
73
100
|
readonly name: string
|
|
74
101
|
readonly duration: Duration.Input
|
|
75
|
-
}): DurableClock => makeClock(options.name,
|
|
102
|
+
}): DurableClock => makeClock(options.name, clockDuration(options.duration))
|
|
76
103
|
|
|
77
104
|
/**
|
|
78
105
|
* Waits inside a flow, using an in-memory action for durations at or
|
|
79
106
|
* below the threshold and scheduling a durable clock for longer durations.
|
|
80
107
|
*
|
|
108
|
+
* Throws a `RangeError` for the same durations {@link make} refuses, and for
|
|
109
|
+
* a malformed, infinite or negative threshold. A durable sleep that would
|
|
110
|
+
* wake after epoch millisecond `Number.MAX_SAFE_INTEGER` dies with a
|
|
111
|
+
* `RangeError` instead of arming its clock.
|
|
112
|
+
*
|
|
81
113
|
* @category sleeping
|
|
82
114
|
* @since 0.1.0
|
|
83
115
|
*/
|
|
@@ -99,7 +131,7 @@ export const sleep = (
|
|
|
99
131
|
Crypto.Crypto | FlowRuntime | FlowInstance
|
|
100
132
|
> => {
|
|
101
133
|
const name = options.name
|
|
102
|
-
const duration =
|
|
134
|
+
const duration = clockDuration(options.duration)
|
|
103
135
|
const inMemoryThreshold = durationFromInput(
|
|
104
136
|
options.inMemoryThreshold ?? defaultInMemoryThreshold,
|
|
105
137
|
"inMemoryThreshold"
|
|
@@ -119,6 +151,17 @@ export const sleep = (
|
|
|
119
151
|
})
|
|
120
152
|
}
|
|
121
153
|
|
|
154
|
+
// A due time past the latest one a store records would fail the park
|
|
155
|
+
// write deep in the engine, so the sleep refuses it here by name.
|
|
156
|
+
const now = yield* Clock.currentTimeMillis
|
|
157
|
+
if (now + Duration.toMillis(duration) > latestDueAtMs) {
|
|
158
|
+
return yield* Effect.die(
|
|
159
|
+
new RangeError(
|
|
160
|
+
`DurableClock: "${name}" would wake after epoch millisecond ${latestDueAtMs}, ` +
|
|
161
|
+
`the latest due time a durable timer records.`
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
}
|
|
122
165
|
const engine = yield* FlowRuntime
|
|
123
166
|
const instance = yield* FlowInstance
|
|
124
167
|
const clock = makeClock(name, duration)
|
package/src/Flow/make.ts
CHANGED
|
@@ -99,7 +99,8 @@ interface MakeOptions<
|
|
|
99
99
|
readonly maxRounds?: number | undefined
|
|
100
100
|
/**
|
|
101
101
|
* How long one execution may take, counted from its journaled first start.
|
|
102
|
-
* A positive finite duration
|
|
102
|
+
* A positive finite duration of at most `Number.MAX_SAFE_INTEGER`
|
|
103
|
+
* milliseconds; see {@link Flow.deadline}.
|
|
103
104
|
*/
|
|
104
105
|
readonly deadline?: Duration.Input | undefined
|
|
105
106
|
readonly annotations?: Context.Context<never>
|
|
@@ -222,6 +223,11 @@ export const make: {
|
|
|
222
223
|
) {
|
|
223
224
|
throw new RangeError(`Flow.make: "${tag}" deadline must be a positive finite duration`)
|
|
224
225
|
}
|
|
226
|
+
// The durable clock that enforces a deadline is due at its start plus the
|
|
227
|
+
// deadline, and a store records that due time as a safe integer.
|
|
228
|
+
if (deadline !== undefined && Duration.toMillis(deadline) > Number.MAX_SAFE_INTEGER) {
|
|
229
|
+
throw new RangeError(`Flow.make: "${tag}" deadline must be at most ${Number.MAX_SAFE_INTEGER} ms`)
|
|
230
|
+
}
|
|
225
231
|
// Captured here, where the stack still names the author's file, and carried
|
|
226
232
|
// as a non-enumerable property so no digest can see it
|
|
227
233
|
// (`internal/DeclarationSite.ts`).
|
package/src/HumanTask.ts
CHANGED
|
@@ -680,7 +680,9 @@ const budgetOf = (payload: Payload): Effect.Effect<number, HumanTaskFailed> => {
|
|
|
680
680
|
const deadlineOf = (payload: Payload): Effect.Effect<Duration.Duration | undefined, HumanTaskFailed> => {
|
|
681
681
|
const timeoutMs = payload.timeoutMs
|
|
682
682
|
if (timeoutMs === undefined) return Effect.succeed(undefined)
|
|
683
|
-
|
|
683
|
+
// The timeout clock is due at its start plus the deadline, and a durable
|
|
684
|
+
// store records that due time as a safe integer.
|
|
685
|
+
return Number.isFinite(timeoutMs) && timeoutMs >= 0 && timeoutMs <= Number.MAX_SAFE_INTEGER
|
|
684
686
|
? Effect.succeed(Duration.millis(timeoutMs))
|
|
685
687
|
: Effect.fail(
|
|
686
688
|
failed(
|
|
@@ -688,8 +690,8 @@ const deadlineOf = (payload: Payload): Effect.Effect<Duration.Duration | undefin
|
|
|
688
690
|
"request_invalid",
|
|
689
691
|
0,
|
|
690
692
|
[],
|
|
691
|
-
`${tag} was called with timeoutMs ${timeoutMs}. A deadline is a
|
|
692
|
-
|
|
693
|
+
`${tag} was called with timeoutMs ${timeoutMs}. A deadline is a number of milliseconds ` +
|
|
694
|
+
`from 0 to ${Number.MAX_SAFE_INTEGER}; the question would be over before it was asked, or ` +
|
|
693
695
|
"never over at all."
|
|
694
696
|
)
|
|
695
697
|
)
|