@workflow/world-testing 4.1.15 → 4.1.16

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.
@@ -50439,7 +50439,7 @@ init_dist();
50439
50439
  init_node();
50440
50440
 
50441
50441
  // ../core/dist/version.js
50442
- var version2 = "4.8.0";
50442
+ var version2 = "4.8.1";
50443
50443
 
50444
50444
  // ../core/dist/runtime/world.js
50445
50445
  var import_node_module = require("node:module");
@@ -53391,7 +53391,6 @@ init_zod();
53391
53391
  // ../world-vercel/dist/http-client.js
53392
53392
  var import_undici2 = __toESM(require_undici(), 1);
53393
53393
  var _dispatcher;
53394
- var _eventsDispatcher;
53395
53394
  var _streamDispatcher;
53396
53395
  var _streamCloseDispatcher;
53397
53396
  var DEFAULT_HEADERS_TIMEOUT_MS = 3e4;
@@ -53450,6 +53449,14 @@ function getEventsAgentOptions() {
53450
53449
  };
53451
53450
  }
53452
53451
  __name(getEventsAgentOptions, "getEventsAgentOptions");
53452
+ function getEventsAgentOptionsNoH2() {
53453
+ return {
53454
+ ...getBaseAgentOptions(),
53455
+ allowH2: false,
53456
+ pipelining: 1
53457
+ };
53458
+ }
53459
+ __name(getEventsAgentOptionsNoH2, "getEventsAgentOptionsNoH2");
53453
53460
  function getStreamAgentOptions() {
53454
53461
  return {
53455
53462
  ...getBaseAgentOptions(),
@@ -53488,10 +53495,10 @@ var STREAM_CLOSE_RETRY_OPTIONS = {
53488
53495
  statusCodes: [429, 500, 502, 503, 504]
53489
53496
  };
53490
53497
  var H2_REBUFFER_MAX_BYTES = 1 << 20;
53491
- function h2MultiplexEnabled() {
53498
+ function h2EventsEnabled() {
53492
53499
  return process.env.WORKFLOW_H2_MULTIPLEX !== "0";
53493
53500
  }
53494
- __name(h2MultiplexEnabled, "h2MultiplexEnabled");
53501
+ __name(h2EventsEnabled, "h2EventsEnabled");
53495
53502
  function contentLength(headers) {
53496
53503
  if (!headers || typeof headers !== "object" || Array.isArray(headers)) {
53497
53504
  return Number.NaN;
@@ -53524,12 +53531,86 @@ function h2MultiplexInterceptor(dispatch) {
53524
53531
  };
53525
53532
  }
53526
53533
  __name(h2MultiplexInterceptor, "h2MultiplexInterceptor");
53534
+ var EVENTS_RECYCLE_AFTER_CONSECUTIVE_FAILURES = 3;
53535
+ var RECYCLE_MIN_INTERVAL_MS = 5e3;
53536
+ var RETIRED_CLOSE_DELAY_MS = 5e3;
53537
+ var RETIRED_DESTROY_DELAY_MS = 6e4;
53538
+ var RECYCLABLE_ERROR_CODES = /* @__PURE__ */ new Set([
53539
+ // Covers H2 stream timeout, frameError and GOAWAY (undici InformationalError).
53540
+ "UND_ERR_INFO",
53541
+ "UND_ERR_HEADERS_TIMEOUT",
53542
+ "UND_ERR_BODY_TIMEOUT"
53543
+ ]);
53544
+ var MAX_CAUSE_DEPTH = 8;
53545
+ function isRecyclableTransportError(error48) {
53546
+ let current = error48;
53547
+ for (let depth = 0; current && depth < MAX_CAUSE_DEPTH; depth++) {
53548
+ const code = current.code;
53549
+ if (typeof code === "string" && RECYCLABLE_ERROR_CODES.has(code)) {
53550
+ return true;
53551
+ }
53552
+ current = current.cause;
53553
+ }
53554
+ return false;
53555
+ }
53556
+ __name(isRecyclableTransportError, "isRecyclableTransportError");
53557
+ function createDispatcherRecycler(factory, label) {
53558
+ let current;
53559
+ let consecutiveFailures = 0;
53560
+ let lastRecycledAt = 0;
53561
+ function retire(stale) {
53562
+ const closeTimer = setTimeout(() => {
53563
+ void Promise.resolve(stale.close?.()).catch(() => void 0);
53564
+ }, RETIRED_CLOSE_DELAY_MS);
53565
+ const destroyTimer = setTimeout(() => {
53566
+ void Promise.resolve(stale.destroy?.()).catch(() => void 0);
53567
+ }, RETIRED_DESTROY_DELAY_MS);
53568
+ closeTimer.unref?.();
53569
+ destroyTimer.unref?.();
53570
+ }
53571
+ __name(retire, "retire");
53572
+ return {
53573
+ get() {
53574
+ current ??= factory();
53575
+ return current;
53576
+ },
53577
+ note(dispatcher, error48) {
53578
+ if (!current || dispatcher !== current)
53579
+ return;
53580
+ if (error48 === void 0) {
53581
+ consecutiveFailures = 0;
53582
+ return;
53583
+ }
53584
+ if (!isRecyclableTransportError(error48))
53585
+ return;
53586
+ consecutiveFailures++;
53587
+ if (consecutiveFailures < EVENTS_RECYCLE_AFTER_CONSECUTIVE_FAILURES) {
53588
+ return;
53589
+ }
53590
+ const now = Date.now();
53591
+ if (now - lastRecycledAt < RECYCLE_MIN_INTERVAL_MS)
53592
+ return;
53593
+ lastRecycledAt = now;
53594
+ consecutiveFailures = 0;
53595
+ const stale = current;
53596
+ current = void 0;
53597
+ console.warn(`[workflow] ${label}: rebuilding connection pool after ${EVENTS_RECYCLE_AFTER_CONSECUTIVE_FAILURES} consecutive transport failures`);
53598
+ retire(stale);
53599
+ }
53600
+ };
53601
+ }
53602
+ __name(createDispatcherRecycler, "createDispatcherRecycler");
53603
+ var eventsRecycler = createDispatcherRecycler(() => createEventsDispatcher(), "events transport");
53604
+ function noteEventsTransportOutcome(dispatcher, error48) {
53605
+ eventsRecycler.note(dispatcher, error48);
53606
+ }
53607
+ __name(noteEventsTransportOutcome, "noteEventsTransportOutcome");
53527
53608
  function getDispatcher(config3) {
53528
53609
  return config3?.dispatcher ?? getDefaultDispatcher();
53529
53610
  }
53530
53611
  __name(getDispatcher, "getDispatcher");
53531
53612
  function getEventsDispatcher(config3) {
53532
- return config3?.dispatcher ?? getDefaultEventsDispatcher();
53613
+ return config3?.dispatcher ?? eventsRecycler.get();
53533
53614
  }
53534
53615
  __name(getEventsDispatcher, "getEventsDispatcher");
53535
53616
  function getStreamDispatcher(config3) {
@@ -53541,8 +53622,12 @@ function getStreamCloseDispatcher(config3) {
53541
53622
  }
53542
53623
  __name(getStreamCloseDispatcher, "getStreamCloseDispatcher");
53543
53624
  function createEventsDispatcher(agentOverrides) {
53544
- const agent = new import_undici2.RetryAgent(new import_undici2.Agent({ ...getEventsAgentOptions(), ...agentOverrides }), getRetryAgentOptions());
53545
- if (!h2MultiplexEnabled()) {
53625
+ const h2 = h2EventsEnabled();
53626
+ const agent = new import_undici2.RetryAgent(new import_undici2.Agent({
53627
+ ...h2 ? getEventsAgentOptions() : getEventsAgentOptionsNoH2(),
53628
+ ...agentOverrides
53629
+ }), getRetryAgentOptions());
53630
+ if (!h2) {
53546
53631
  return agent;
53547
53632
  }
53548
53633
  return withBoundLifecycle(agent, agent.compose(h2MultiplexInterceptor));
@@ -53563,11 +53648,6 @@ function getDefaultDispatcher() {
53563
53648
  return _dispatcher;
53564
53649
  }
53565
53650
  __name(getDefaultDispatcher, "getDefaultDispatcher");
53566
- function getDefaultEventsDispatcher() {
53567
- _eventsDispatcher ??= createEventsDispatcher();
53568
- return _eventsDispatcher;
53569
- }
53570
- __name(getDefaultEventsDispatcher, "getDefaultEventsDispatcher");
53571
53651
  function getDefaultStreamDispatcher() {
53572
53652
  _streamDispatcher ??= createStreamDispatcher(STREAM_RETRY_OPTIONS);
53573
53653
  return _streamDispatcher;
@@ -53762,7 +53842,7 @@ function httpClientSpanAttributes(args) {
53762
53842
  }
53763
53843
  __name(httpClientSpanAttributes, "httpClientSpanAttributes");
53764
53844
  async function instrumentedFetch(opts) {
53765
- const { method, url: url2, headers, body, dispatcher, peerService = "workflow-server", timeoutMs = REQUEST_TIMEOUT_MS, signal: callerSignal, injectTraceContext = true, cacheBust = true, logLabel, buildError } = opts;
53845
+ const { method, url: url2, headers, body, dispatcher, peerService = "workflow-server", timeoutMs = REQUEST_TIMEOUT_MS, signal: callerSignal, injectTraceContext = true, cacheBust = true, logLabel, buildError, onTransportOutcome } = opts;
53766
53846
  const label = logLabel ?? url2;
53767
53847
  return trace4(`http ${method}`, { kind: await getSpanKind3("CLIENT") }, async (span) => {
53768
53848
  span?.setAttributes(httpClientSpanAttributes({ method, url: url2, peerService }));
@@ -53785,6 +53865,7 @@ async function instrumentedFetch(opts) {
53785
53865
  });
53786
53866
  } catch (error48) {
53787
53867
  const elapsed = Date.now() - start2;
53868
+ onTransportOutcome?.(error48);
53788
53869
  if (error48 instanceof Error && (error48.name === "TimeoutError" || error48.name === "AbortError")) {
53789
53870
  const timeoutError = new WorkflowWorldError(`${method} ${label} timed out after ${elapsed}ms`, { url: url2, cause: error48 });
53790
53871
  span?.setAttributes({ ...ErrorType2("TIMEOUT") });
@@ -53794,6 +53875,7 @@ async function instrumentedFetch(opts) {
53794
53875
  throw error48;
53795
53876
  }
53796
53877
  const ms2 = Date.now() - start2;
53878
+ onTransportOutcome?.();
53797
53879
  httpLog(method, label, response, ms2);
53798
53880
  span?.setAttributes({ ...HttpResponseStatusCode2(response.status) });
53799
53881
  if (!response.ok) {
@@ -60949,7 +61031,7 @@ var import_oidc3 = __toESM(require_dist(), 1);
60949
61031
  init_dist();
60950
61032
 
60951
61033
  // ../world-vercel/dist/version.js
60952
- var version3 = "4.6.1";
61034
+ var version3 = "4.6.2";
60953
61035
 
60954
61036
  // ../world-vercel/dist/utils.js
60955
61037
  var WORKFLOW_SERVER_URL_OVERRIDE = "";
@@ -61767,12 +61849,18 @@ __name(readerToIterator, "readerToIterator");
61767
61849
 
61768
61850
  // ../world-vercel/dist/events-v4.js
61769
61851
  async function fetchV4(url2, init, config3, opName) {
61852
+ const dispatcher = getEventsDispatcher(config3);
61770
61853
  return instrumentedFetch({
61771
61854
  method: init.method,
61772
61855
  url: url2,
61773
61856
  headers: init.headers,
61774
61857
  body: init.body,
61775
- dispatcher: getEventsDispatcher(config3),
61858
+ dispatcher,
61859
+ // Repeated transport failures retire the shared events pool and the next
61860
+ // request builds a fresh one. undici keeps a black-holed HTTP/2 session in
61861
+ // service indefinitely, so without this every request routed onto it fails
61862
+ // until the compute instance is recycled — see noteEventsTransportOutcome.
61863
+ onTransportOutcome: /* @__PURE__ */ __name((error48) => noteEventsTransportOutcome(dispatcher, error48), "onTransportOutcome"),
61776
61864
  timeoutMs: null,
61777
61865
  logLabel: opName,
61778
61866
  buildError: /* @__PURE__ */ __name(async (response) => errorFromV4Response(response.status, headersToRecord(response.headers), await response.text(), opName, url2), "buildError")
@@ -6,6 +6,16 @@
6
6
  "stepId": "step//./workflows/event-limit//tick"
7
7
  }
8
8
  },
9
+ "workflows/hooks.ts": {
10
+ "writeEvent": {
11
+ "stepId": "step//./workflows/hooks//writeEvent"
12
+ }
13
+ },
14
+ "workflows/addition.ts": {
15
+ "add": {
16
+ "stepId": "step//./workflows/addition//add"
17
+ }
18
+ },
9
19
  "workflows/noop.ts": {
10
20
  "noop": {
11
21
  "stepId": "step//./workflows/noop//noop"
@@ -18,17 +28,7 @@
18
28
  },
19
29
  "workflow/dist/stdlib.js": {
20
30
  "fetch": {
21
- "stepId": "step//workflow@4.8.0//fetch"
22
- }
23
- },
24
- "workflows/hooks.ts": {
25
- "writeEvent": {
26
- "stepId": "step//./workflows/hooks//writeEvent"
27
- }
28
- },
29
- "workflows/addition.ts": {
30
- "add": {
31
- "stepId": "step//./workflows/addition//add"
31
+ "stepId": "step//workflow@4.8.1//fetch"
32
32
  }
33
33
  },
34
34
  "workflow/dist/internal/builtins.js": {
@@ -109,16 +109,16 @@
109
109
  }
110
110
  }
111
111
  },
112
- "workflows/noop.ts": {
113
- "brokenWf": {
114
- "workflowId": "workflow//./workflows/noop//brokenWf",
112
+ "workflows/hooks.ts": {
113
+ "collectWithHook": {
114
+ "workflowId": "workflow//./workflows/hooks//collectWithHook",
115
115
  "graph": {
116
116
  "nodes": [
117
117
  {
118
118
  "id": "start",
119
119
  "type": "workflowStart",
120
120
  "data": {
121
- "label": "Start: brokenWf",
121
+ "label": "Start: collectWithHook",
122
122
  "nodeKind": "workflow_start"
123
123
  }
124
124
  },
@@ -126,18 +126,22 @@
126
126
  "id": "node_0",
127
127
  "type": "step",
128
128
  "data": {
129
- "label": "noop",
129
+ "label": "writeEvent",
130
130
  "nodeKind": "step",
131
- "stepId": "step//./workflows/noop//noop"
131
+ "stepId": "step//./workflows/hooks//writeEvent"
132
132
  }
133
133
  },
134
134
  {
135
135
  "id": "node_1",
136
136
  "type": "step",
137
137
  "data": {
138
- "label": "noop",
138
+ "label": "writeEvent",
139
139
  "nodeKind": "step",
140
- "stepId": "step//./workflows/noop//noop"
140
+ "stepId": "step//./workflows/hooks//writeEvent"
141
+ },
142
+ "metadata": {
143
+ "loopId": "loop_0",
144
+ "loopIsAwait": true
141
145
  }
142
146
  },
143
147
  {
@@ -156,6 +160,12 @@
156
160
  "target": "node_0",
157
161
  "type": "default"
158
162
  },
163
+ {
164
+ "id": "e_node_1_back_node_1",
165
+ "source": "node_1",
166
+ "target": "node_1",
167
+ "type": "loop"
168
+ },
159
169
  {
160
170
  "id": "e_node_0_node_1",
161
171
  "source": "node_0",
@@ -172,16 +182,16 @@
172
182
  }
173
183
  }
174
184
  },
175
- "workflows/null-byte.ts": {
176
- "nullByteWorkflow": {
177
- "workflowId": "workflow//./workflows/null-byte//nullByteWorkflow",
185
+ "workflows/addition.ts": {
186
+ "addition": {
187
+ "workflowId": "workflow//./workflows/addition//addition",
178
188
  "graph": {
179
189
  "nodes": [
180
190
  {
181
191
  "id": "start",
182
192
  "type": "workflowStart",
183
193
  "data": {
184
- "label": "Start: nullByteWorkflow",
194
+ "label": "Start: addition",
185
195
  "nodeKind": "workflow_start"
186
196
  }
187
197
  },
@@ -189,9 +199,9 @@
189
199
  "id": "node_0",
190
200
  "type": "step",
191
201
  "data": {
192
- "label": "nullByteStep",
202
+ "label": "add",
193
203
  "nodeKind": "step",
194
- "stepId": "step//./workflows/null-byte//nullByteStep"
204
+ "stepId": "step//./workflows/addition//add"
195
205
  }
196
206
  },
197
207
  {
@@ -220,16 +230,16 @@
220
230
  }
221
231
  }
222
232
  },
223
- "workflows/hooks.ts": {
224
- "collectWithHook": {
225
- "workflowId": "workflow//./workflows/hooks//collectWithHook",
233
+ "workflows/noop.ts": {
234
+ "brokenWf": {
235
+ "workflowId": "workflow//./workflows/noop//brokenWf",
226
236
  "graph": {
227
237
  "nodes": [
228
238
  {
229
239
  "id": "start",
230
240
  "type": "workflowStart",
231
241
  "data": {
232
- "label": "Start: collectWithHook",
242
+ "label": "Start: brokenWf",
233
243
  "nodeKind": "workflow_start"
234
244
  }
235
245
  },
@@ -237,22 +247,18 @@
237
247
  "id": "node_0",
238
248
  "type": "step",
239
249
  "data": {
240
- "label": "writeEvent",
250
+ "label": "noop",
241
251
  "nodeKind": "step",
242
- "stepId": "step//./workflows/hooks//writeEvent"
252
+ "stepId": "step//./workflows/noop//noop"
243
253
  }
244
254
  },
245
255
  {
246
256
  "id": "node_1",
247
257
  "type": "step",
248
258
  "data": {
249
- "label": "writeEvent",
259
+ "label": "noop",
250
260
  "nodeKind": "step",
251
- "stepId": "step//./workflows/hooks//writeEvent"
252
- },
253
- "metadata": {
254
- "loopId": "loop_0",
255
- "loopIsAwait": true
261
+ "stepId": "step//./workflows/noop//noop"
256
262
  }
257
263
  },
258
264
  {
@@ -271,12 +277,6 @@
271
277
  "target": "node_0",
272
278
  "type": "default"
273
279
  },
274
- {
275
- "id": "e_node_1_back_node_1",
276
- "source": "node_1",
277
- "target": "node_1",
278
- "type": "loop"
279
- },
280
280
  {
281
281
  "id": "e_node_0_node_1",
282
282
  "source": "node_0",
@@ -293,16 +293,16 @@
293
293
  }
294
294
  }
295
295
  },
296
- "workflows/addition.ts": {
297
- "addition": {
298
- "workflowId": "workflow//./workflows/addition//addition",
296
+ "workflows/null-byte.ts": {
297
+ "nullByteWorkflow": {
298
+ "workflowId": "workflow//./workflows/null-byte//nullByteWorkflow",
299
299
  "graph": {
300
300
  "nodes": [
301
301
  {
302
302
  "id": "start",
303
303
  "type": "workflowStart",
304
304
  "data": {
305
- "label": "Start: addition",
305
+ "label": "Start: nullByteWorkflow",
306
306
  "nodeKind": "workflow_start"
307
307
  }
308
308
  },
@@ -310,9 +310,9 @@
310
310
  "id": "node_0",
311
311
  "type": "step",
312
312
  "data": {
313
- "label": "add",
313
+ "label": "nullByteStep",
314
314
  "nodeKind": "step",
315
- "stepId": "step//./workflows/addition//add"
315
+ "stepId": "step//./workflows/null-byte//nullByteStep"
316
316
  }
317
317
  },
318
318
  {