effect-cf 0.50.0 → 0.51.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/CHANGELOG.md +14 -0
- package/README.md +2 -0
- package/dist/DurableObjectAlarm.d.mts +68 -15
- package/dist/DurableObjectAlarm.mjs +261 -110
- package/dist/DurableObjectContainer.d.mts +1 -1
- package/dist/DurableObjectContainer.mjs +1 -1
- package/dist/DurableObjectRpcWebSocket.d.mts +2 -2
- package/dist/DurableObjectRpcWebSocket.mjs +2 -6
- package/dist/DurableObjectStorage.d.mts +2 -9
- package/dist/DurableObjectStorage.mjs +1 -14
- package/dist/DurableObjectWebSocket.d.mts +10 -2
- package/dist/DurableObjectWebSocket.mjs +18 -2
- package/dist/RpcTracing.mjs +1 -1
- package/package.json +1 -1
- package/src/DurableObjectAlarm.ts +536 -202
- package/src/DurableObjectRpcWebSocket.ts +4 -14
- package/src/DurableObjectStorage.ts +2 -59
- package/src/DurableObjectWebSocket.ts +24 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# effect-cf
|
|
2
2
|
|
|
3
|
+
## 0.51.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#199](https://github.com/danieljvdm/effect-cf/pull/199) [`abe14de`](https://github.com/danieljvdm/effect-cf/commit/abe14de1f6d563ad000220bfe7b0d03266efaf12) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Bound Durable Object alarm failures and handler self-rearms with exponential backoff, a one-second floor, an eight-attempt no-progress budget and hourly parked recovery. Add content-free parking reports, durable status inspection, monotonic source progress and transactional min-merge scheduling.
|
|
8
|
+
|
|
9
|
+
Add an optional DurableObjectAlarm.ScheduleConfiguration reference, installed with Layer.succeed, for the retry floor, finite attempt budget, parked recovery interval and product repeat floor. Defaults remain one second, eight attempts, one hour and one minute. Validation preserves a one-second retry/repeat minimum and at most hourly parked recovery; increasing the budget cannot resume parked work without progress.
|
|
10
|
+
|
|
11
|
+
Dispatch and reconcile from indexed effective wake deadlines, with automatic migration of retained schedules, instead of scanning the backlog on every mutation. Failures retry independently and cannot block unrelated due work.
|
|
12
|
+
|
|
13
|
+
BREAKING: remove platform setAlarm, setAlarmAfter and deleteAlarm from the public storage and transaction wrappers. Migrate deadline writes to scheduleAlarm, earliest-deadline merges to scheduleAlarmEarlier, and atomic storage changes to alarms.transaction. Product repeatEvery schedules now require at least one minute by default; provide ScheduleConfiguration for a different product repeat floor. Remove ordered failure handling and ProcessDueAlarmsMode: drop options.mode and replace ordered failure policies/actions with retry. Enroll dependent work on completion events. Due alarms dispatch by effective wake deadline and storage key; retry deadlines remain separate from logical scheduledAt.
|
|
14
|
+
|
|
15
|
+
Add DurableObjectWebSocket.installKeepalive with the exact effect-cf:ping / effect-cf:pong text protocol. RPC Ping/Pong auto-response now stays enabled during pending requests, so keepalives never wake the object. After eviction, lost ordinary RPCs reset on the next application message; clients should use operation deadlines to recover lost work. See the [wakeup migration guide](https://github.com/danieljvdm/effect-cf/blob/main/docs/durable-object-wakeups.md) for migration and recovery details.
|
|
16
|
+
|
|
3
17
|
## 0.50.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ See the [runtime performance guide](https://github.com/danieljvdm/effect-cf/blob
|
|
|
12
12
|
|
|
13
13
|
For typed WebSocket RPC clients whose connection lifetime is owned by an Effect layer, see the [WebSocket RPC guide](https://github.com/danieljvdm/effect-cf/blob/main/docs/websocket-rpc.md).
|
|
14
14
|
|
|
15
|
+
Durable Object alarms bound unchanged retries and self-rearms, and hibernating sockets handle keepalives without waking the object. See the [wakeup and migration guide](https://github.com/danieljvdm/effect-cf/blob/main/docs/durable-object-wakeups.md).
|
|
16
|
+
|
|
15
17
|
`DurableObjectContainer.layer` adds native `ctx.container` control to `DurableObject.make`: runtime image selection, command execution, filesystem snapshots, networking, and idle timeouts. See the [container guide](https://github.com/danieljvdm/effect-cf/blob/main/docs/containers.md) for setup and migration from the legacy Container and Sandbox classes.
|
|
16
18
|
|
|
17
19
|
## Worker
|
|
@@ -7,9 +7,38 @@ import * as Layer from "effect/Layer";
|
|
|
7
7
|
import * as Duration from "effect/Duration";
|
|
8
8
|
import * as DateTime from "effect/DateTime";
|
|
9
9
|
declare namespace DurableObjectAlarm_d_exports {
|
|
10
|
-
export { AlarmDefinitionConfig, AlarmDefinitionEntry, AlarmDefinitionPayload, AlarmDefinitions, AlarmFailurePolicy, AlarmPayload, AlarmPayloadSchema, AlarmRef, AlarmRegistration, AlarmRetryPolicy, AlarmScheduler, AlarmService, AlarmTagClass, AlarmTransaction, DefinedAlarmEvent, DefinedAlarmHandlers, DefinedAlarmScheduler, DefinedAlarmTransaction, DefinedScheduleAlarmInput, DurableObjectAlarm, DurableObjectAlarmError, DurableObjectAlarmEvent, InvalidAlarmPayloadError, InvalidAlarmRefError, InvalidProcessDueAlarmsOptionsError, InvalidRepeatEveryError, ProcessDueAlarmsFailure, ProcessDueAlarmsFailureAction, ProcessDueAlarmsHandler,
|
|
11
|
-
}
|
|
10
|
+
export { AlarmDefinitionConfig, AlarmDefinitionEntry, AlarmDefinitionPayload, AlarmDefinitions, AlarmFailurePolicy, AlarmParked, AlarmPayload, AlarmPayloadSchema, AlarmRef, AlarmRegistration, AlarmReporter, AlarmRetryPolicy, AlarmScheduler, AlarmService, AlarmStatus, AlarmTagClass, AlarmTransaction, DEFAULT_MIN_REPEAT_INTERVAL_MS, DefinedAlarmEvent, DefinedAlarmHandlers, DefinedAlarmScheduler, DefinedAlarmTransaction, DefinedScheduleAlarmInput, DurableObjectAlarm, DurableObjectAlarmError, DurableObjectAlarmEvent, InvalidAlarmPayloadError, InvalidAlarmRefError, InvalidProcessDueAlarmsOptionsError, InvalidRepeatEveryError, InvalidScheduleConfigurationError, MIN_REPEAT_INTERVAL_MS, MIN_RETRY_DELAY_MS, PARKED_RETRY_DELAY_MS, ProcessDueAlarmsFailure, ProcessDueAlarmsFailureAction, ProcessDueAlarmsHandler, ProcessDueAlarmsOptions, ProcessDueAlarmsResult, ScheduleAlarmInput, ScheduleConfiguration, StoredAlarmDecodeError, Tag, UNCHANGED_ATTEMPT_BUDGET, define, processDue };
|
|
11
|
+
}
|
|
12
|
+
declare const MIN_RETRY_DELAY_MS = 1000;
|
|
13
|
+
/** Default unchanged-attempt budget. */
|
|
14
|
+
declare const UNCHANGED_ATTEMPT_BUDGET = 8;
|
|
15
|
+
/** Minimum and default parked recovery interval. */
|
|
16
|
+
declare const PARKED_RETRY_DELAY_MS = 3600000;
|
|
17
|
+
/** Absolute product repeat floor. */
|
|
18
|
+
declare const MIN_REPEAT_INTERVAL_MS = 1000;
|
|
19
|
+
/** Default product schedule floor. Never use repeats to poll state. */
|
|
20
|
+
declare const DEFAULT_MIN_REPEAT_INTERVAL_MS = 60000;
|
|
21
|
+
interface ScheduleConfiguration {
|
|
22
|
+
/** Retry floor, at least one second. Defaults to one second. */
|
|
23
|
+
readonly minimumRetryDelay?: Duration.Input;
|
|
24
|
+
/** Positive safe integer. Defaults to eight unchanged attempts. */
|
|
25
|
+
readonly unchangedAttemptBudget?: number;
|
|
26
|
+
/** Recovery interval, at least one hour and the retry floor. Defaults to one hour. */
|
|
27
|
+
readonly parkedRetryDelay?: Duration.Input;
|
|
28
|
+
/** Product repeat floor, at least one second. Defaults to one minute. */
|
|
29
|
+
readonly minimumRepeatInterval?: Duration.Input;
|
|
30
|
+
}
|
|
31
|
+
/** Optional policy overrides. Provide with Layer.succeed in the Durable Object's application layer. */
|
|
32
|
+
declare const ScheduleConfiguration: Context.Reference<ScheduleConfiguration>;
|
|
12
33
|
type AlarmPayload = S.Json;
|
|
34
|
+
/** Content-free: no alarm identifiers, payload, error text or consumer state. */
|
|
35
|
+
declare const AlarmParked: S.TaggedStruct<"AlarmParked", {
|
|
36
|
+
readonly attempts: S.Int;
|
|
37
|
+
readonly retryAt: S.DateTimeUtc;
|
|
38
|
+
}>;
|
|
39
|
+
type AlarmParked = typeof AlarmParked.Type;
|
|
40
|
+
/** Install with Layer.succeed / Effect.provideService. Reporting cannot undo a committed guard. */
|
|
41
|
+
declare const AlarmReporter: Context.Reference<(event: AlarmParked) => Effect.Effect<void>>;
|
|
13
42
|
declare const InvalidAlarmRefError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
14
43
|
readonly _tag: "InvalidAlarmRefError";
|
|
15
44
|
} & Readonly<A>;
|
|
@@ -42,6 +71,14 @@ declare class InvalidProcessDueAlarmsOptionsError extends InvalidProcessDueAlarm
|
|
|
42
71
|
}> {
|
|
43
72
|
get message(): string;
|
|
44
73
|
}
|
|
74
|
+
declare const InvalidScheduleConfigurationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
75
|
+
readonly _tag: "InvalidScheduleConfigurationError";
|
|
76
|
+
} & Readonly<A>;
|
|
77
|
+
declare class InvalidScheduleConfigurationError extends InvalidScheduleConfigurationError_base<{
|
|
78
|
+
readonly cause: unknown;
|
|
79
|
+
}> {
|
|
80
|
+
get message(): string;
|
|
81
|
+
}
|
|
45
82
|
declare const StoredAlarmDecodeError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
46
83
|
readonly _tag: "StoredAlarmDecodeError";
|
|
47
84
|
} & Readonly<A>;
|
|
@@ -51,7 +88,7 @@ declare class StoredAlarmDecodeError extends StoredAlarmDecodeError_base<{
|
|
|
51
88
|
}> {
|
|
52
89
|
get message(): string;
|
|
53
90
|
}
|
|
54
|
-
type DurableObjectAlarmError = InvalidAlarmPayloadError | InvalidAlarmRefError | InvalidProcessDueAlarmsOptionsError | InvalidRepeatEveryError | StorageOperationError | StoredAlarmDecodeError;
|
|
91
|
+
type DurableObjectAlarmError = InvalidAlarmPayloadError | InvalidAlarmRefError | InvalidProcessDueAlarmsOptionsError | InvalidRepeatEveryError | InvalidScheduleConfigurationError | StorageOperationError | StoredAlarmDecodeError;
|
|
55
92
|
declare const DurableObjectAlarmEvent: S.TaggedUnion<{
|
|
56
93
|
readonly AlarmDue: S.TaggedStruct<"AlarmDue", {
|
|
57
94
|
readonly id: S.NonEmptyString;
|
|
@@ -66,13 +103,17 @@ type AlarmRef<Tag extends string = string> = {
|
|
|
66
103
|
readonly id: string;
|
|
67
104
|
readonly tag: Tag;
|
|
68
105
|
};
|
|
69
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* Arm a logical deadline. External enrollment is progress; handler self-rearms consume a budget.
|
|
108
|
+
* Reusing `{tag, id}` replaces an alarm. Product repeats use the configured floor and run after completion.
|
|
109
|
+
*/
|
|
70
110
|
type ScheduleAlarmInput<Tag extends string = string> = AlarmRef<Tag> & {
|
|
71
111
|
readonly payload: AlarmPayload;
|
|
72
112
|
readonly repeatEvery?: Duration.Input;
|
|
73
113
|
readonly runAt: DateTime.Utc;
|
|
114
|
+
/** Optional monotonic source cursor. Only a strictly increasing cursor resets a live budget. */
|
|
115
|
+
readonly progress?: number;
|
|
74
116
|
};
|
|
75
|
-
type ProcessDueAlarmsMode = "isolated" | "ordered";
|
|
76
117
|
interface ProcessDueAlarmsFailure {
|
|
77
118
|
readonly cause: unknown;
|
|
78
119
|
readonly event?: DurableObjectAlarmEvent;
|
|
@@ -83,10 +124,9 @@ interface ProcessDueAlarmsFailure {
|
|
|
83
124
|
interface ProcessDueAlarmsResult {
|
|
84
125
|
readonly failed: readonly ProcessDueAlarmsFailure[];
|
|
85
126
|
readonly handled: readonly DurableObjectAlarmEvent[];
|
|
127
|
+
readonly parked: readonly AlarmParked[];
|
|
86
128
|
}
|
|
87
|
-
type ProcessDueAlarmsFailureAction = "
|
|
88
|
-
readonly mode: "ordered";
|
|
89
|
-
} | {
|
|
129
|
+
type ProcessDueAlarmsFailureAction = "retry" | "skip-and-advance-repeat" | {
|
|
90
130
|
readonly mode: "retry";
|
|
91
131
|
readonly retryFailedAfter?: Duration.Input;
|
|
92
132
|
} | {
|
|
@@ -94,8 +134,6 @@ type ProcessDueAlarmsFailureAction = "ordered" | "retry" | "skip-and-advance-rep
|
|
|
94
134
|
};
|
|
95
135
|
interface ProcessDueAlarmsOptions<OnFailureR = never, OnFailureE = never> {
|
|
96
136
|
readonly limit?: number;
|
|
97
|
-
/** `isolated` retries only the failed row; `ordered` stops before later rows. */
|
|
98
|
-
readonly mode?: ProcessDueAlarmsMode;
|
|
99
137
|
readonly onFailure?: (failure: ProcessDueAlarmsFailure) => Effect.Effect<ProcessDueAlarmsFailureAction | void, OnFailureE, OnFailureR>;
|
|
100
138
|
readonly retryFailedAfter?: Duration.Input;
|
|
101
139
|
}
|
|
@@ -104,7 +142,13 @@ type ProcessDueAlarmsHandler<R = never, E = never> = (event: DurableObjectAlarmE
|
|
|
104
142
|
* Alarm mutations owned by one transaction callback. Run them in the callback's
|
|
105
143
|
* fiber; forked work and use after the callback ends fail with StorageOperationError.
|
|
106
144
|
*/
|
|
107
|
-
type AlarmTransaction = Pick<AlarmScheduler, "scheduleAlarm" | "cancelAlarm">;
|
|
145
|
+
type AlarmTransaction = Pick<AlarmScheduler, "scheduleAlarm" | "scheduleAlarmEarlier" | "cancelAlarm">;
|
|
146
|
+
interface AlarmStatus {
|
|
147
|
+
readonly attempts: number;
|
|
148
|
+
readonly parked: boolean;
|
|
149
|
+
readonly runAt: DateTime.Utc;
|
|
150
|
+
readonly retryAt: DateTime.Utc | undefined;
|
|
151
|
+
}
|
|
108
152
|
/** Own `storage.setAlarm()` exclusively: a Durable Object has one platform alarm timestamp. */
|
|
109
153
|
type AlarmScheduler = {
|
|
110
154
|
/**
|
|
@@ -121,14 +165,21 @@ type AlarmScheduler = {
|
|
|
121
165
|
*/
|
|
122
166
|
readonly transaction: <A, E, R>(closure: (alarms: AlarmTransaction) => Effect.Effect<A, E, R>) => Effect.Effect<A, E | StorageOperationError, R>;
|
|
123
167
|
readonly cancelAlarm: (input: AlarmRef) => Effect.Effect<void, InvalidAlarmRefError | StorageOperationError>;
|
|
124
|
-
/**
|
|
168
|
+
/** Inspect retained work, including hourly recovery deadlines. */
|
|
169
|
+
readonly getAlarmStatus: (input: AlarmRef) => Effect.Effect<AlarmStatus | undefined, InvalidAlarmRefError | StorageOperationError>;
|
|
170
|
+
/**
|
|
171
|
+
* Dispatch by effective wake deadline, then storage key. Failures retry independently.
|
|
172
|
+
* Conditional acknowledgements preserve handler replacements; alarms are at-least-once.
|
|
173
|
+
*/
|
|
125
174
|
readonly processDueAlarms: <R = never, E = never, OnFailureR = never, OnFailureE = never>(handle: ProcessDueAlarmsHandler<R, E>, options?: ProcessDueAlarmsOptions<OnFailureR, OnFailureE>) => Effect.Effect<ProcessDueAlarmsResult, E | OnFailureE | DurableObjectAlarmError, R | OnFailureR>;
|
|
126
175
|
/** A failed platform setAlarm rolls back the logical schedule in the same transaction. */
|
|
127
|
-
readonly scheduleAlarm: (input: ScheduleAlarmInput) => Effect.Effect<void, InvalidAlarmPayloadError | InvalidAlarmRefError | InvalidRepeatEveryError | StorageOperationError>;
|
|
176
|
+
readonly scheduleAlarm: (input: ScheduleAlarmInput) => Effect.Effect<void, InvalidAlarmPayloadError | InvalidAlarmRefError | InvalidRepeatEveryError | InvalidScheduleConfigurationError | StorageOperationError>;
|
|
177
|
+
/** Atomically min-merge a logical deadline. Preserves an earlier alarm's payload and repeat. */
|
|
178
|
+
readonly scheduleAlarmEarlier: AlarmScheduler["scheduleAlarm"];
|
|
128
179
|
};
|
|
129
180
|
declare const processDue: <R = never, E = never, OnFailureR = never, OnFailureE = never>(handle: ProcessDueAlarmsHandler<R, E>, options?: ProcessDueAlarmsOptions<OnFailureR, OnFailureE>) => Effect.Effect<ProcessDueAlarmsResult, E | OnFailureE | DurableObjectAlarmError, OnFailureR | R | DurableObjectAlarm>;
|
|
130
181
|
type AlarmPayloadSchema = S.Codec<any, any, never, never>;
|
|
131
|
-
type AlarmFailurePolicy = "
|
|
182
|
+
type AlarmFailurePolicy = "retry" | "skip-and-advance-repeat";
|
|
132
183
|
interface AlarmRetryPolicy {
|
|
133
184
|
readonly initialDelay?: Duration.Input;
|
|
134
185
|
}
|
|
@@ -152,6 +203,7 @@ type DefinedScheduleAlarmInput<Definitions extends AlarmDefinitions> = { readonl
|
|
|
152
203
|
}; }[keyof Definitions & string];
|
|
153
204
|
interface DefinedAlarmTransaction<Definitions extends AlarmDefinitions> {
|
|
154
205
|
readonly scheduleAlarm: (input: DefinedScheduleAlarmInput<Definitions>) => ReturnType<AlarmScheduler["scheduleAlarm"]>;
|
|
206
|
+
readonly scheduleAlarmEarlier: DefinedAlarmTransaction<Definitions>["scheduleAlarm"];
|
|
155
207
|
readonly cancelAlarm: (input: AlarmRef<keyof Definitions & string>) => ReturnType<AlarmScheduler["cancelAlarm"]>;
|
|
156
208
|
}
|
|
157
209
|
declare const TypedAlarmSchedulerTypeId: unique symbol;
|
|
@@ -163,6 +215,7 @@ interface AlarmService {
|
|
|
163
215
|
}
|
|
164
216
|
interface DefinedAlarmScheduler<Definitions extends AlarmDefinitions> extends DefinedAlarmTransaction<Definitions> {
|
|
165
217
|
readonly [TypedAlarmSchedulerTypeId]: typeof TypedAlarmSchedulerTypeId;
|
|
218
|
+
readonly getAlarmStatus: (input: AlarmRef<keyof Definitions & string>) => ReturnType<AlarmScheduler["getAlarmStatus"]>;
|
|
166
219
|
readonly transaction: <A, E, R>(closure: (alarms: DefinedAlarmTransaction<Definitions>) => Effect.Effect<A, E, R>) => Effect.Effect<A, E | StorageOperationError, R>;
|
|
167
220
|
}
|
|
168
221
|
/** Registers a dispatcher and the service authorized to schedule its alarms. */
|
|
@@ -184,4 +237,4 @@ declare class DurableObjectAlarm extends DurableObjectAlarm_base {
|
|
|
184
237
|
static readonly layer: Layer.Layer<DurableObjectAlarm, never, DurableObjectState>;
|
|
185
238
|
}
|
|
186
239
|
//#endregion
|
|
187
|
-
export { AlarmDefinitionConfig, AlarmDefinitionEntry, AlarmDefinitionPayload, AlarmDefinitions, AlarmFailurePolicy, AlarmPayload, AlarmPayloadSchema, AlarmRef, AlarmRegistration, AlarmRetryPolicy, AlarmScheduler, AlarmService, AlarmTagClass, AlarmTransaction, DefinedAlarmEvent, DefinedAlarmHandlers, DefinedAlarmScheduler, DefinedAlarmTransaction, DefinedScheduleAlarmInput, DurableObjectAlarm, DurableObjectAlarmError, DurableObjectAlarmEvent, DurableObjectAlarm_d_exports, InvalidAlarmPayloadError, InvalidAlarmRefError, InvalidProcessDueAlarmsOptionsError, InvalidRepeatEveryError, ProcessDueAlarmsFailure, ProcessDueAlarmsFailureAction, ProcessDueAlarmsHandler,
|
|
240
|
+
export { AlarmDefinitionConfig, AlarmDefinitionEntry, AlarmDefinitionPayload, AlarmDefinitions, AlarmFailurePolicy, AlarmParked, AlarmPayload, AlarmPayloadSchema, AlarmRef, AlarmRegistration, AlarmReporter, AlarmRetryPolicy, AlarmScheduler, AlarmService, AlarmStatus, AlarmTagClass, AlarmTransaction, DEFAULT_MIN_REPEAT_INTERVAL_MS, DefinedAlarmEvent, DefinedAlarmHandlers, DefinedAlarmScheduler, DefinedAlarmTransaction, DefinedScheduleAlarmInput, DurableObjectAlarm, DurableObjectAlarmError, DurableObjectAlarmEvent, DurableObjectAlarm_d_exports, InvalidAlarmPayloadError, InvalidAlarmRefError, InvalidProcessDueAlarmsOptionsError, InvalidRepeatEveryError, InvalidScheduleConfigurationError, MIN_REPEAT_INTERVAL_MS, MIN_RETRY_DELAY_MS, PARKED_RETRY_DELAY_MS, ProcessDueAlarmsFailure, ProcessDueAlarmsFailureAction, ProcessDueAlarmsHandler, ProcessDueAlarmsOptions, ProcessDueAlarmsResult, ScheduleAlarmInput, ScheduleConfiguration, StoredAlarmDecodeError, Tag, UNCHANGED_ATTEMPT_BUDGET, define, processDue };
|