@btravstack/temporal-worker 0.48.0 → 0.49.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/README.md +5 -0
- package/dist/index.d.mts +13 -10
- package/dist/index.mjs +21 -9
- package/dist/schedule.d.mts +1 -1
- package/package.json +14 -14
package/README.md
CHANGED
|
@@ -160,6 +160,9 @@ itself, inside its own error qualifier, so a contract it cannot satisfy is a
|
|
|
160
160
|
startup `Err`, not a defect. `runtimeInfo()` reads `{ taskQueue, namespace }`
|
|
161
161
|
back once the worker is polling.
|
|
162
162
|
|
|
163
|
+
Activity-piece DI identities include the contract task queue. Separate worker
|
|
164
|
+
contracts can reuse keys without sharing a port; wire activity names stay unchanged.
|
|
165
|
+
|
|
163
166
|
A worker polling for several workflows can be several slices instead of one
|
|
164
167
|
record: `TemporalWorkflowActivities(contract, key)({ inject: { name: Dep }, unit, fork, sync })` mints a
|
|
165
168
|
provider for ONE workflow's activities (or a contract-global activity),
|
|
@@ -218,6 +221,8 @@ optional peers. See
|
|
|
218
221
|
|
|
219
222
|
## Options
|
|
220
223
|
|
|
224
|
+
- `taskQueue`: pins `TEMPORAL_TASK_QUEUE`, defaulting to the contract queue; see the [reference](https://btravstack.github.io/btravstack/reference/temporal-worker).
|
|
225
|
+
|
|
221
226
|
`TemporalModule(name)({...})` takes the starter's options plus `activities`
|
|
222
227
|
and the module lists (`imports`, `provides`, `exports`, `needs`). It is the
|
|
223
228
|
only way to compose the starter, which is not exported:
|
package/dist/index.d.mts
CHANGED
|
@@ -58,7 +58,7 @@ declare const WORKFLOW_ACTIVITIES_PREFIX = "TemporalWorkflowActivities:";
|
|
|
58
58
|
* slices claiming one workflow di's duplicate-provider defect rather than a
|
|
59
59
|
* silent merge.
|
|
60
60
|
*/
|
|
61
|
-
type WorkflowActivitiesPortOf<C extends ContractDefinition, K extends ActivitiesKeyOf<C>> = PortClassOf<`${typeof WORKFLOW_ACTIVITIES_PREFIX}${K}`, ActivitiesRecordOf<C>[K]>;
|
|
61
|
+
type WorkflowActivitiesPortOf<C extends ContractDefinition, K extends ActivitiesKeyOf<C>> = PortClassOf<`${typeof WORKFLOW_ACTIVITIES_PREFIX}${C["taskQueue"]}:${K}`, ActivitiesRecordOf<C>[K]>;
|
|
62
62
|
/**
|
|
63
63
|
* What a minted piece returns. A piece naming its own `fork` owes that
|
|
64
64
|
* module's unmet needs, and leaves nothing for the root's `unit.activity` to
|
|
@@ -66,6 +66,7 @@ type WorkflowActivitiesPortOf<C extends ContractDefinition, K extends Activities
|
|
|
66
66
|
*/
|
|
67
67
|
type MintedActivities<C extends ContractDefinition, K extends ActivitiesKeyOf<C>, N, U extends Readonly<Record<string, AnyPort>>, M extends AnyUnitModule | undefined> = Provider<InstanceType<WorkflowActivitiesPortOf<C, K>>, never, N | UnitNeedsOf$1<M>> & {
|
|
68
68
|
readonly port: WorkflowActivitiesPortOf<C, K>;
|
|
69
|
+
readonly _activityKey?: K;
|
|
69
70
|
/** Phantom: the ports this piece injects, which the root's `unit.activity` must export. */
|
|
70
71
|
readonly _declared?: undefined extends M ? InstanceType<U[keyof U]> : never;
|
|
71
72
|
};
|
|
@@ -80,16 +81,16 @@ type ScopedActivitiesOf<C extends ContractDefinition, K extends ActivitiesKeyOf<
|
|
|
80
81
|
*
|
|
81
82
|
* A worker that polls one queue for several workflows is several pieces, each
|
|
82
83
|
* declaring the services its own activities call;
|
|
83
|
-
* `TemporalActivities(contract)([...])` composes them.
|
|
84
|
-
*
|
|
85
|
-
*
|
|
84
|
+
* `TemporalActivities(contract)([...])` composes them. The contract types both
|
|
85
|
+
* `key` and the record and supplies the task queue that namespaces the port.
|
|
86
|
+
* An undeclared activity is a compile error rather than a startup failure.
|
|
86
87
|
*
|
|
87
88
|
* `key` is any top-level key of the activities record, which includes a
|
|
88
89
|
* contract-global activity as well as a workflow; the name is imprecise in that
|
|
89
90
|
* one case deliberately, since narrowing it would lock such a contract out of
|
|
90
91
|
* the split.
|
|
91
92
|
*
|
|
92
|
-
*
|
|
93
|
+
* The contract's task queue and the key identify the port; wire activity names stay unchanged.
|
|
93
94
|
*
|
|
94
95
|
* `unit` declares the ports the activities read off `context.unit`, resolved
|
|
95
96
|
* out of the fork the attempt opened; the root's `unit.activity` module must
|
|
@@ -140,6 +141,7 @@ declare const TemporalConfig_base: import("@btravstack/di").PortClass<"TemporalC
|
|
|
140
141
|
export declare class TemporalConfig extends TemporalConfig_base<{
|
|
141
142
|
readonly address: string;
|
|
142
143
|
readonly namespace: string;
|
|
144
|
+
readonly taskQueue: string;
|
|
143
145
|
/** Temporal's `shutdownGraceTime`, in milliseconds. */
|
|
144
146
|
readonly gracePeriodMs: number;
|
|
145
147
|
/** Temporal's `shutdownForceTime`, in milliseconds. */
|
|
@@ -191,6 +193,8 @@ type TemporalTuning<Unit extends AnyUnitModule | undefined = undefined, Converte
|
|
|
191
193
|
readonly address?: string;
|
|
192
194
|
/** Pins `TemporalConfig.namespace` instead of reading `TEMPORAL_NAMESPACE`. */
|
|
193
195
|
readonly namespace?: string;
|
|
196
|
+
/** Physical polling queue, independent of the logical contract and DI identities. Pins TEMPORAL_TASK_QUEUE. */
|
|
197
|
+
readonly taskQueue?: string;
|
|
194
198
|
/**
|
|
195
199
|
* Pins `TemporalConfig.forceAfterMs` instead of reading
|
|
196
200
|
* `TEMPORAL_FORCE_AFTER_MS` (default `15_000`) — Temporal's
|
|
@@ -244,7 +248,7 @@ type TemporalOptions<C extends ContractDefinition, Unit extends AnyUnitModule |
|
|
|
244
248
|
//#endregion
|
|
245
249
|
//#region src/temporal-module.d.ts
|
|
246
250
|
/** The starter's own module, as the sugar adds it to the application's imports. */
|
|
247
|
-
type TemporalStarter<C extends ContractDefinition, Unit extends AnyUnitModule | undefined, Converter extends DataConverterPort> = Module<TemporalRuntime | TemporalConfig | TemporalConnection, ConfigInvalid | TemporalUnreachable, EnvReading<never, "TEMPORAL_ADDRESS" | "TEMPORAL_NAMESPACE" | "TEMPORAL_GRACE_PERIOD_MS" | "TEMPORAL_FORCE_AFTER_MS"> | Scope | ActivitiesInstanceOf<C> | UnitNeedsOf$1<Unit> | InstanceType<Converter>>;
|
|
251
|
+
type TemporalStarter<C extends ContractDefinition, Unit extends AnyUnitModule | undefined, Converter extends DataConverterPort> = Module<TemporalRuntime | TemporalConfig | TemporalConnection, ConfigInvalid | TemporalUnreachable, EnvReading<never, "TEMPORAL_ADDRESS" | "TEMPORAL_NAMESPACE" | "TEMPORAL_TASK_QUEUE" | "TEMPORAL_GRACE_PERIOD_MS" | "TEMPORAL_FORCE_AFTER_MS"> | Scope | ActivitiesInstanceOf<C> | UnitNeedsOf$1<Unit> | InstanceType<Converter>>;
|
|
248
252
|
/** The application's imports plus the starter — the tuple `Module(name)` is handed. */
|
|
249
253
|
type Imports<I extends readonly AnyModule[], C extends ContractDefinition, Unit extends AnyUnitModule | undefined, Converter extends DataConverterPort> = readonly [...I, TemporalStarter<C, Unit, Converter>];
|
|
250
254
|
/** The activities provider plus the application's own — the tuple `Module(name)` is handed. */
|
|
@@ -292,6 +296,7 @@ export declare const TemporalModule: <const Name extends string>(name: Name) =>
|
|
|
292
296
|
/** One piece of the activities record — what `TemporalWorkflowActivities(contract, key)(…)` returns. */
|
|
293
297
|
type PieceOf<C extends ContractDefinition> = { readonly [K in ActivitiesKeyOf<C>]: {
|
|
294
298
|
readonly port: WorkflowActivitiesPortOf<C, K>;
|
|
299
|
+
readonly _activityKey?: K;
|
|
295
300
|
/** Phantom, carrying the ports the piece injects off `context.unit`. */
|
|
296
301
|
readonly _declared?: unknown;
|
|
297
302
|
}; }[ActivitiesKeyOf<C>];
|
|
@@ -299,11 +304,9 @@ type PieceOf<C extends ContractDefinition> = { readonly [K in ActivitiesKeyOf<C>
|
|
|
299
304
|
type DeclaredOf<T extends readonly {
|
|
300
305
|
readonly _declared?: unknown;
|
|
301
306
|
}[]> = NonNullable<T[number]["_declared"]>;
|
|
302
|
-
/** The key a piece carries
|
|
307
|
+
/** The contract key a piece carries independently of its queue namespace. */
|
|
303
308
|
type KeyOfPiece<P> = P extends {
|
|
304
|
-
readonly
|
|
305
|
-
readonly portId: `${typeof WORKFLOW_ACTIVITIES_PREFIX}${infer K}`;
|
|
306
|
-
};
|
|
309
|
+
readonly _activityKey?: infer K;
|
|
307
310
|
} ? K : never;
|
|
308
311
|
/** The record's top-level keys no piece in `T` covers. */
|
|
309
312
|
type Uncovered<C extends ContractDefinition, T extends readonly PieceOf<C>[]> = Exclude<ActivitiesKeyOf<C>, KeyOfPiece<T[number]>>;
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Observers, RuntimePort, RuntimeStartFailed, composeByPrefix, dispatchUnit, infrastructureExports, mintPiece, noObserverMember, releasedBy, withUnitRecord } from "@btravstack/core";
|
|
2
2
|
import { Module, Port, Provider } from "@btravstack/di";
|
|
3
|
-
import { Config, Env } from "@btravstack/config";
|
|
3
|
+
import { Config, ConfigFieldInvalid, Env } from "@btravstack/config";
|
|
4
4
|
import { declareActivitiesHandler } from "@temporal-contract/worker/activity";
|
|
5
5
|
import { msToNumber } from "@temporalio/common";
|
|
6
6
|
import { NativeConnection, Worker } from "@temporalio/worker";
|
|
7
7
|
import { Ok, OkAsync, TaggedError, fromPromise, fromSafePromise, fromThrowable } from "unthrown";
|
|
8
8
|
import { activityInfo } from "@temporalio/activity";
|
|
9
|
+
import { defineContractBinding } from "@temporal-contract/contract";
|
|
9
10
|
//#region src/unit.ts
|
|
10
11
|
/**
|
|
11
12
|
* One entry of the activities record — a contract-global activity's own
|
|
@@ -61,16 +62,16 @@ const WORKFLOW_ACTIVITIES_PREFIX = "TemporalWorkflowActivities:";
|
|
|
61
62
|
*
|
|
62
63
|
* A worker that polls one queue for several workflows is several pieces, each
|
|
63
64
|
* declaring the services its own activities call;
|
|
64
|
-
* `TemporalActivities(contract)([...])` composes them.
|
|
65
|
-
*
|
|
66
|
-
*
|
|
65
|
+
* `TemporalActivities(contract)([...])` composes them. The contract types both
|
|
66
|
+
* `key` and the record and supplies the task queue that namespaces the port.
|
|
67
|
+
* An undeclared activity is a compile error rather than a startup failure.
|
|
67
68
|
*
|
|
68
69
|
* `key` is any top-level key of the activities record, which includes a
|
|
69
70
|
* contract-global activity as well as a workflow; the name is imprecise in that
|
|
70
71
|
* one case deliberately, since narrowing it would lock such a contract out of
|
|
71
72
|
* the split.
|
|
72
73
|
*
|
|
73
|
-
*
|
|
74
|
+
* The contract's task queue and the key identify the port; wire activity names stay unchanged.
|
|
74
75
|
*
|
|
75
76
|
* `unit` declares the ports the activities read off `context.unit`, resolved
|
|
76
77
|
* out of the fork the attempt opened; the root's `unit.activity` module must
|
|
@@ -84,7 +85,7 @@ const WORKFLOW_ACTIVITIES_PREFIX = "TemporalWorkflowActivities:";
|
|
|
84
85
|
* declares are then checked against this module, here.
|
|
85
86
|
*/
|
|
86
87
|
const TemporalWorkflowActivities = (contract, key) => {
|
|
87
|
-
const port = class extends Port(`${WORKFLOW_ACTIVITIES_PREFIX}${key}`) {};
|
|
88
|
+
const port = class extends Port(`${WORKFLOW_ACTIVITIES_PREFIX}${contract.taskQueue}:${key}`) {};
|
|
88
89
|
return (options) => mintPiece(port, (record, entry) => withFork(withUnit(record, entry), options.fork))(options);
|
|
89
90
|
};
|
|
90
91
|
//#endregion
|
|
@@ -154,6 +155,17 @@ const metaFor = () => {
|
|
|
154
155
|
};
|
|
155
156
|
};
|
|
156
157
|
//#endregion
|
|
158
|
+
//#region src/task-queue.ts
|
|
159
|
+
const taskQueueField = (contract) => {
|
|
160
|
+
const field = Config.string("TEMPORAL_TASK_QUEUE", { default: contract.taskQueue });
|
|
161
|
+
const check = (taskQueue) => fromThrowable(() => defineContractBinding(contract, { taskQueue }).taskQueue, (cause) => new ConfigFieldInvalid({ reason: String(cause) }))();
|
|
162
|
+
return {
|
|
163
|
+
variable: field.variable,
|
|
164
|
+
parse: (raw) => field.parse(raw).flatMap(check),
|
|
165
|
+
check
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
//#endregion
|
|
157
169
|
//#region src/temporal-runtime.ts
|
|
158
170
|
/**
|
|
159
171
|
* Where the Temporal service is, as a service: the starter binds it from the
|
|
@@ -214,6 +226,7 @@ const temporal = (options) => {
|
|
|
214
226
|
const config = Config.provider(TemporalConfig)(Config.object({
|
|
215
227
|
address: Config.pinned(address, Config.string("TEMPORAL_ADDRESS", { default: "127.0.0.1:7233" })),
|
|
216
228
|
namespace: Config.pinned(namespace, Config.string("TEMPORAL_NAMESPACE", { default: "default" })),
|
|
229
|
+
taskQueue: Config.pinned(options.taskQueue, taskQueueField(options.contract)),
|
|
217
230
|
gracePeriodMs: Config.pinned(durationMs(options.gracePeriod), Config.integer("TEMPORAL_GRACE_PERIOD_MS", {
|
|
218
231
|
default: DEFAULT_GRACE_MS,
|
|
219
232
|
min: 0
|
|
@@ -269,8 +282,7 @@ const startFailed = (cause) => new RuntimeStartFailed({
|
|
|
269
282
|
});
|
|
270
283
|
const heldByWorker = (cause) => cause instanceof Error && cause.name === "IllegalStateError";
|
|
271
284
|
const createWorker = (host, connection, config, activities, options, observers, dataConverter) => {
|
|
272
|
-
const { taskQueue } =
|
|
273
|
-
const { namespace } = config;
|
|
285
|
+
const { namespace, taskQueue } = config;
|
|
274
286
|
return fromThrowable(() => declareActivitiesHandler({
|
|
275
287
|
contract: options.contract,
|
|
276
288
|
middleware: activityUnits(host, observers, (key) => forkOf(activities[key]) ?? options.unit?.activity),
|
|
@@ -377,7 +389,7 @@ const TemporalModule = (name) => (options) => {
|
|
|
377
389
|
* and two slices claiming one key are di's duplicate-provider defect at build.
|
|
378
390
|
*/
|
|
379
391
|
const TemporalActivities = (contract) => {
|
|
380
|
-
return composeByPrefix(TemporalActivitiesPort, WORKFLOW_ACTIVITIES_PREFIX
|
|
392
|
+
return composeByPrefix(TemporalActivitiesPort, `${WORKFLOW_ACTIVITIES_PREFIX}${contract.taskQueue}:`, withUnit);
|
|
381
393
|
};
|
|
382
394
|
//#endregion
|
|
383
395
|
export { ActivityInput, TemporalActivities, TemporalConfig, TemporalConnection, TemporalModule, TemporalRuntime, TemporalUnreachable, TemporalWorkflowActivities };
|
package/dist/schedule.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncResult } from "unthrown";
|
|
2
|
-
import { ScheduleNotFoundError, TypedScheduleClient, TypedScheduleCreateOptions, WorkflowValidationError } from "@temporal-contract/client";
|
|
3
2
|
import { ContractDefinition } from "@temporal-contract/contract";
|
|
3
|
+
import { ScheduleNotFoundError, TypedScheduleClient, TypedScheduleCreateOptions, WorkflowValidationError } from "@temporal-contract/client";
|
|
4
4
|
//#region src/schedule.d.ts
|
|
5
5
|
/** Whether the schedule had to be created, or was already there and had its spec reconciled. */
|
|
6
6
|
export type ScheduleOutcome = "created" | "updated";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btravstack/temporal-worker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.0",
|
|
4
4
|
"description": "The Temporal worker runtime for @btravstack/core: one unit per activity attempt, and a drain that honours the kernel's deadline",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"graceful-shutdown",
|
|
@@ -52,15 +52,15 @@
|
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@btravstack/config": "0.
|
|
56
|
-
"@btravstack/core": "0.
|
|
57
|
-
"@btravstack/di": "0.
|
|
55
|
+
"@btravstack/config": "0.49.0",
|
|
56
|
+
"@btravstack/core": "0.49.0",
|
|
57
|
+
"@btravstack/di": "0.49.0",
|
|
58
58
|
"@btravstack/internal-test-infra": "0.0.0",
|
|
59
|
-
"@btravstack/testing": "0.
|
|
59
|
+
"@btravstack/testing": "0.49.0",
|
|
60
60
|
"@btravstack/tsconfig": "0.4.0",
|
|
61
|
-
"@temporal-contract/client": "8.0.0-beta.
|
|
62
|
-
"@temporal-contract/contract": "8.0.0-beta.
|
|
63
|
-
"@temporal-contract/worker": "8.0.0-beta.
|
|
61
|
+
"@temporal-contract/client": "8.0.0-beta.15",
|
|
62
|
+
"@temporal-contract/contract": "8.0.0-beta.15",
|
|
63
|
+
"@temporal-contract/worker": "8.0.0-beta.15",
|
|
64
64
|
"@temporalio/activity": "1.24.0",
|
|
65
65
|
"@temporalio/client": "1.24.0",
|
|
66
66
|
"@temporalio/common": "1.24.0",
|
|
@@ -78,12 +78,12 @@
|
|
|
78
78
|
"zod": "4.6.7"
|
|
79
79
|
},
|
|
80
80
|
"peerDependencies": {
|
|
81
|
-
"@btravstack/config": "^0.
|
|
82
|
-
"@btravstack/core": "^0.
|
|
83
|
-
"@btravstack/di": "^0.
|
|
84
|
-
"@temporal-contract/client": "^8.0.0-beta.
|
|
85
|
-
"@temporal-contract/contract": "^8.0.0-beta.
|
|
86
|
-
"@temporal-contract/worker": "^8.0.0-beta.
|
|
81
|
+
"@btravstack/config": "^0.49.0",
|
|
82
|
+
"@btravstack/core": "^0.49.0",
|
|
83
|
+
"@btravstack/di": "^0.49.0",
|
|
84
|
+
"@temporal-contract/client": "^8.0.0-beta.15",
|
|
85
|
+
"@temporal-contract/contract": "^8.0.0-beta.15",
|
|
86
|
+
"@temporal-contract/worker": "^8.0.0-beta.15",
|
|
87
87
|
"@temporalio/activity": "^1.24.0",
|
|
88
88
|
"@temporalio/common": "^1.24.0",
|
|
89
89
|
"@temporalio/worker": "^1.24.0",
|