@iworkflow/temporal 0.7.0 → 0.8.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 +13 -2
- package/dist/workflow.js +3 -1
- package/package.json +2 -2
- package/src/index.ts +13 -2
- package/src/workflow.ts +6 -1
package/dist/index.js
CHANGED
|
@@ -141,7 +141,15 @@ var wrap = (h, ready = async () => {}) => ({
|
|
|
141
141
|
var TEMPORAL_STEP = {
|
|
142
142
|
heartbeat: async (details) => Context.current().heartbeat(details),
|
|
143
143
|
lastHeartbeat: async () => Context.current().info.heartbeatDetails,
|
|
144
|
-
attempt: () => Context.current().info.attempt
|
|
144
|
+
attempt: () => Context.current().info.attempt,
|
|
145
|
+
info: () => {
|
|
146
|
+
const { workflowExecution, activityId } = Context.current().info;
|
|
147
|
+
const { workflowId, runId } = workflowExecution ?? {};
|
|
148
|
+
if (!workflowId || !runId)
|
|
149
|
+
throw new Error("stepInfo: шаг вне процесса Temporal");
|
|
150
|
+
return { workflowId, runId, stepId: activityId };
|
|
151
|
+
},
|
|
152
|
+
signal: () => Context.current().cancellationSignal
|
|
145
153
|
};
|
|
146
154
|
var temporalStep = (fn) => stepScope(alsScope).run(TEMPORAL_STEP, fn);
|
|
147
155
|
function temporalActivities(activities) {
|
|
@@ -284,7 +292,10 @@ async function temporalClient(opts = {}) {
|
|
|
284
292
|
await ready();
|
|
285
293
|
const h = await client.workflow.start(target.flow, {
|
|
286
294
|
...startOptions(target, args, o),
|
|
287
|
-
...o.onExisting === "reject"
|
|
295
|
+
...o.onExisting === "reject" || o.reuseClosedId ? {
|
|
296
|
+
workflowIdConflictPolicy: "FAIL",
|
|
297
|
+
workflowIdReusePolicy: o.reuseClosedId ? "ALLOW_DUPLICATE" : "REJECT_DUPLICATE"
|
|
298
|
+
} : { workflowIdConflictPolicy: "USE_EXISTING" }
|
|
288
299
|
}).catch((e) => {
|
|
289
300
|
throw fromTemporal(e);
|
|
290
301
|
});
|
package/dist/workflow.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
deprecatePatch,
|
|
7
7
|
executeChild,
|
|
8
8
|
getExternalWorkflowHandle,
|
|
9
|
+
log,
|
|
9
10
|
ParentClosePolicy,
|
|
10
11
|
patched,
|
|
11
12
|
proxyActivities,
|
|
@@ -15,7 +16,7 @@ import {
|
|
|
15
16
|
TemporalFailure,
|
|
16
17
|
workflowInfo
|
|
17
18
|
} from "@temporalio/workflow";
|
|
18
|
-
import { checkPriority, DEFAULT_PRIORITY, FlowError as FlowError2 } from "@iworkflow/core";
|
|
19
|
+
import { checkPriority, DEFAULT_PRIORITY, FlowError as FlowError2, plainAttrs } from "@iworkflow/core";
|
|
19
20
|
|
|
20
21
|
// src/failure.ts
|
|
21
22
|
import {
|
|
@@ -144,6 +145,7 @@ function temporalFlow(flow, patches = []) {
|
|
|
144
145
|
throw e;
|
|
145
146
|
throw new FlowError2(`процесса ${workflowId} нет или он завершён`, { reason: "not-found" });
|
|
146
147
|
}),
|
|
148
|
+
log: async (level, message, attrs) => log[level](message, plainAttrs(attrs)),
|
|
147
149
|
async setState(key, value) {
|
|
148
150
|
state.set(key, value);
|
|
149
151
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iworkflow/temporal",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Temporal adapter for @iworkflow/core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"workflow",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"prepack": "bun run build"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@iworkflow/core": "^0.
|
|
44
|
+
"@iworkflow/core": "^0.8.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@temporalio/activity": "^1.24.0",
|
package/src/index.ts
CHANGED
|
@@ -78,6 +78,14 @@ const TEMPORAL_STEP: StepRuntime = {
|
|
|
78
78
|
heartbeat: async (details) => Context.current().heartbeat(details),
|
|
79
79
|
lastHeartbeat: async () => Context.current().info.heartbeatDetails,
|
|
80
80
|
attempt: () => Context.current().info.attempt,
|
|
81
|
+
info: () => {
|
|
82
|
+
// Пустой id как ключ идемпотентности склеил бы записи разных процессов — отказ.
|
|
83
|
+
const { workflowExecution, activityId } = Context.current().info;
|
|
84
|
+
const { workflowId, runId } = workflowExecution ?? {};
|
|
85
|
+
if (!workflowId || !runId) throw new Error("stepInfo: шаг вне процесса Temporal");
|
|
86
|
+
return { workflowId, runId, stepId: activityId };
|
|
87
|
+
},
|
|
88
|
+
signal: () => Context.current().cancellationSignal,
|
|
81
89
|
};
|
|
82
90
|
|
|
83
91
|
/** Один вызов шага в рантайме Temporal без обёртки отказов — для тестов в MockActivityEnvironment. */
|
|
@@ -250,8 +258,11 @@ export async function temporalClient(opts: TemporalOptions & { lazy?: boolean }
|
|
|
250
258
|
const h = await client.workflow
|
|
251
259
|
.start(target.flow, {
|
|
252
260
|
...startOptions(target, args, o),
|
|
253
|
-
...(o.onExisting === "reject"
|
|
254
|
-
? {
|
|
261
|
+
...(o.onExisting === "reject" || o.reuseClosedId
|
|
262
|
+
? {
|
|
263
|
+
workflowIdConflictPolicy: "FAIL" as const,
|
|
264
|
+
workflowIdReusePolicy: o.reuseClosedId ? ("ALLOW_DUPLICATE" as const) : ("REJECT_DUPLICATE" as const),
|
|
265
|
+
}
|
|
255
266
|
: { workflowIdConflictPolicy: "USE_EXISTING" as const }),
|
|
256
267
|
})
|
|
257
268
|
.catch((e) => {
|
package/src/workflow.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
deprecatePatch,
|
|
9
9
|
executeChild,
|
|
10
10
|
getExternalWorkflowHandle,
|
|
11
|
+
log,
|
|
11
12
|
ParentClosePolicy,
|
|
12
13
|
patched,
|
|
13
14
|
proxyActivities,
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
workflowInfo,
|
|
19
20
|
} from "@temporalio/workflow";
|
|
20
21
|
|
|
21
|
-
import { checkPriority, DEFAULT_PRIORITY, FlowError, type ChildOptions, type Flow, type FlowContext, type StepOptions } from "@iworkflow/core";
|
|
22
|
+
import { checkPriority, DEFAULT_PRIORITY, FlowError, plainAttrs, type ChildOptions, type Flow, type FlowContext, type StepOptions } from "@iworkflow/core";
|
|
22
23
|
import { fromTemporal, toTemporal } from "./failure";
|
|
23
24
|
|
|
24
25
|
export const SIGNAL = "iwf.signal";
|
|
@@ -105,6 +106,7 @@ export function temporalFlow(flow: Flow, patches: string[] = []) {
|
|
|
105
106
|
},
|
|
106
107
|
sleep: (ms) => sleep(ms),
|
|
107
108
|
async recv<T>(topic: string, timeoutMs: number) {
|
|
109
|
+
// 0 и меньше — таймер 1 мс (так было и до 0.8): отдаёт активацию, цикл опроса не виснет.
|
|
108
110
|
const ready = await condition(() => (inbox.get(topic)?.length ?? 0) > 0, timeoutMs);
|
|
109
111
|
return ready ? (inbox.get(topic)!.shift() as T) : null;
|
|
110
112
|
},
|
|
@@ -115,6 +117,9 @@ export function temporalFlow(flow: Flow, patches: string[] = []) {
|
|
|
115
117
|
if (!(e instanceof TemporalFailure)) throw e;
|
|
116
118
|
throw new FlowError(`процесса ${workflowId} нет или он завершён`, { reason: "not-found" });
|
|
117
119
|
}),
|
|
120
|
+
// log песочницы молчит при переигрывании.
|
|
121
|
+
// Неклонируемые attrs (функция, BigInt) уронили бы активацию при отправке из песочницы.
|
|
122
|
+
log: async (level, message, attrs) => log[level](message, plainAttrs(attrs)),
|
|
118
123
|
async setState(key, value) {
|
|
119
124
|
state.set(key, value);
|
|
120
125
|
},
|