@workflow/world-testing 4.1.16 → 4.1.18
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.
|
|
50442
|
+
var version2 = "4.8.3";
|
|
50443
50443
|
|
|
50444
50444
|
// ../core/dist/runtime/world.js
|
|
50445
50445
|
var import_node_module = require("node:module");
|
|
@@ -64035,30 +64035,74 @@ function getStepFunction(stepId) {
|
|
|
64035
64035
|
return void 0;
|
|
64036
64036
|
}
|
|
64037
64037
|
__name(getStepFunction, "getStepFunction");
|
|
64038
|
-
|
|
64038
|
+
var DEFER_BEHIND = {
|
|
64039
|
+
hook: ["wait", "step"],
|
|
64040
|
+
wait: ["hook", "step"],
|
|
64041
|
+
step: ["wait", "hook", "step"]
|
|
64042
|
+
};
|
|
64043
|
+
function resolvesOnItsOwn(barriers, index, entry, memo) {
|
|
64044
|
+
const cached2 = memo.get(index);
|
|
64045
|
+
if (cached2 !== void 0) {
|
|
64046
|
+
return cached2;
|
|
64047
|
+
}
|
|
64048
|
+
const result = computeResolvesOnItsOwn(barriers, index, entry, memo);
|
|
64049
|
+
memo.set(index, result);
|
|
64050
|
+
return result;
|
|
64051
|
+
}
|
|
64052
|
+
__name(resolvesOnItsOwn, "resolvesOnItsOwn");
|
|
64053
|
+
function computeResolvesOnItsOwn(barriers, index, entry, memo) {
|
|
64054
|
+
if (!entry.armed) {
|
|
64055
|
+
return false;
|
|
64056
|
+
}
|
|
64057
|
+
if (entry.kind === "step") {
|
|
64058
|
+
return true;
|
|
64059
|
+
}
|
|
64060
|
+
const deferBehind = DEFER_BEHIND[entry.kind];
|
|
64061
|
+
for (const [otherIndex, other] of barriers) {
|
|
64062
|
+
if (otherIndex < index && deferBehind.includes(other.kind) && !resolvesOnItsOwn(barriers, otherIndex, other, memo)) {
|
|
64063
|
+
return false;
|
|
64064
|
+
}
|
|
64065
|
+
}
|
|
64066
|
+
return true;
|
|
64067
|
+
}
|
|
64068
|
+
__name(computeResolvesOnItsOwn, "computeResolvesOnItsOwn");
|
|
64069
|
+
async function awaitEarlierDeliveries(ctx, eventIndex, kind) {
|
|
64039
64070
|
if (eventIndex === void 0 || !ctx.pendingDeliveryBarriers || ctx.pendingDeliveryBarriers.size === 0) {
|
|
64040
64071
|
return;
|
|
64041
64072
|
}
|
|
64073
|
+
const barriers = ctx.pendingDeliveryBarriers;
|
|
64074
|
+
const deferBehind = DEFER_BEHIND[kind];
|
|
64042
64075
|
const earlier = [];
|
|
64043
|
-
|
|
64044
|
-
|
|
64045
|
-
|
|
64076
|
+
const selfResolving = /* @__PURE__ */ new Map();
|
|
64077
|
+
for (const [index, entry] of barriers) {
|
|
64078
|
+
if (index >= eventIndex || !deferBehind.includes(entry.kind)) {
|
|
64079
|
+
continue;
|
|
64046
64080
|
}
|
|
64081
|
+
if (kind === "step" && !resolvesOnItsOwn(barriers, index, entry, selfResolving)) {
|
|
64082
|
+
continue;
|
|
64083
|
+
}
|
|
64084
|
+
earlier.push(entry.delivered);
|
|
64047
64085
|
}
|
|
64048
64086
|
if (earlier.length > 0) {
|
|
64049
64087
|
await Promise.all(earlier);
|
|
64088
|
+
await new Promise((resolve3) => setTimeout(resolve3, 0));
|
|
64050
64089
|
}
|
|
64051
64090
|
}
|
|
64052
64091
|
__name(awaitEarlierDeliveries, "awaitEarlierDeliveries");
|
|
64053
|
-
function registerDeliveryBarrier(ctx, eventIndex, kind) {
|
|
64092
|
+
function registerDeliveryBarrier(ctx, eventIndex, kind, options = {}) {
|
|
64054
64093
|
const barriers = ctx.pendingDeliveryBarriers;
|
|
64055
64094
|
if (!barriers || eventIndex === void 0) {
|
|
64056
64095
|
return { markDelivered: /* @__PURE__ */ __name(() => {
|
|
64057
|
-
}, "markDelivered")
|
|
64096
|
+
}, "markDelivered"), arm: /* @__PURE__ */ __name(() => {
|
|
64097
|
+
}, "arm") };
|
|
64058
64098
|
}
|
|
64059
64099
|
let done = false;
|
|
64060
64100
|
const { promise: promise2, resolve: resolve3 } = withResolvers();
|
|
64061
|
-
const entry = {
|
|
64101
|
+
const entry = {
|
|
64102
|
+
kind,
|
|
64103
|
+
delivered: promise2,
|
|
64104
|
+
armed: options.armed ?? true
|
|
64105
|
+
};
|
|
64062
64106
|
barriers.set(eventIndex, entry);
|
|
64063
64107
|
const finish = /* @__PURE__ */ __name(() => {
|
|
64064
64108
|
if (done) {
|
|
@@ -64071,12 +64115,35 @@ function registerDeliveryBarrier(ctx, eventIndex, kind) {
|
|
|
64071
64115
|
resolve3();
|
|
64072
64116
|
}, "finish");
|
|
64073
64117
|
scheduleWhenIdle(ctx, finish);
|
|
64074
|
-
return {
|
|
64118
|
+
return {
|
|
64119
|
+
markDelivered: finish,
|
|
64120
|
+
arm: /* @__PURE__ */ __name(() => {
|
|
64121
|
+
entry.armed = true;
|
|
64122
|
+
}, "arm")
|
|
64123
|
+
};
|
|
64075
64124
|
}
|
|
64076
64125
|
__name(registerDeliveryBarrier, "registerDeliveryBarrier");
|
|
64126
|
+
function hasParkedCommittedDelivery(ctx) {
|
|
64127
|
+
const barriers = ctx.pendingDeliveryBarriers;
|
|
64128
|
+
if (!barriers || barriers.size === 0) {
|
|
64129
|
+
return false;
|
|
64130
|
+
}
|
|
64131
|
+
const selfResolving = /* @__PURE__ */ new Map();
|
|
64132
|
+
for (const [index, entry] of barriers) {
|
|
64133
|
+
if (resolvesOnItsOwn(barriers, index, entry, selfResolving)) {
|
|
64134
|
+
return true;
|
|
64135
|
+
}
|
|
64136
|
+
}
|
|
64137
|
+
return false;
|
|
64138
|
+
}
|
|
64139
|
+
__name(hasParkedCommittedDelivery, "hasParkedCommittedDelivery");
|
|
64140
|
+
function isDeliveryIdle(ctx) {
|
|
64141
|
+
return ctx.pendingDeliveries === 0 && !hasParkedCommittedDelivery(ctx);
|
|
64142
|
+
}
|
|
64143
|
+
__name(isDeliveryIdle, "isDeliveryIdle");
|
|
64077
64144
|
function scheduleWhenIdle(ctx, fn) {
|
|
64078
64145
|
const check2 = /* @__PURE__ */ __name(() => {
|
|
64079
|
-
if (ctx
|
|
64146
|
+
if (!isDeliveryIdle(ctx)) {
|
|
64080
64147
|
ctx.promiseQueue.then(() => {
|
|
64081
64148
|
setTimeout(check2, 0);
|
|
64082
64149
|
});
|
|
@@ -66167,6 +66234,7 @@ __name(customRandom, "customRandom");
|
|
|
66167
66234
|
init_node();
|
|
66168
66235
|
|
|
66169
66236
|
// ../core/dist/events-consumer.js
|
|
66237
|
+
var DEFERRED_CHECK_DELAY_MS = 100;
|
|
66170
66238
|
var EventConsumerResult;
|
|
66171
66239
|
(function(EventConsumerResult2) {
|
|
66172
66240
|
EventConsumerResult2[EventConsumerResult2["Consumed"] = 0] = "Consumed";
|
|
@@ -66183,6 +66251,7 @@ var EventsConsumer = class {
|
|
|
66183
66251
|
onConsumedEvent;
|
|
66184
66252
|
onUnconsumedEvent;
|
|
66185
66253
|
getPromiseQueue;
|
|
66254
|
+
isDeliveryIdle;
|
|
66186
66255
|
pendingUnconsumedCheck = null;
|
|
66187
66256
|
pendingUnconsumedTimeout = null;
|
|
66188
66257
|
unconsumedCheckVersion = 0;
|
|
@@ -66192,6 +66261,7 @@ var EventsConsumer = class {
|
|
|
66192
66261
|
this.onConsumedEvent = options.onConsumedEvent;
|
|
66193
66262
|
this.onUnconsumedEvent = options.onUnconsumedEvent;
|
|
66194
66263
|
this.getPromiseQueue = options.getPromiseQueue;
|
|
66264
|
+
this.isDeliveryIdle = options.isDeliveryIdle ?? (() => true);
|
|
66195
66265
|
}
|
|
66196
66266
|
/**
|
|
66197
66267
|
* Registers a callback function to be called after an event has been consumed
|
|
@@ -66275,16 +66345,58 @@ var EventsConsumer = class {
|
|
|
66275
66345
|
// resumes -> the next hook payload starts hydrating).
|
|
66276
66346
|
() => new Promise((resolve3) => setTimeout(resolve3, 0))
|
|
66277
66347
|
).then(() => this.getPromiseQueue()).then(() => {
|
|
66278
|
-
this.
|
|
66279
|
-
this.pendingUnconsumedTimeout =
|
|
66280
|
-
|
|
66281
|
-
this.
|
|
66282
|
-
|
|
66283
|
-
|
|
66284
|
-
|
|
66348
|
+
this.whenDeliveryIdle(checkVersion, () => {
|
|
66349
|
+
this.pendingUnconsumedTimeout = setTimeout(() => {
|
|
66350
|
+
this.pendingUnconsumedTimeout = null;
|
|
66351
|
+
if (this.unconsumedCheckVersion === checkVersion) {
|
|
66352
|
+
this.pendingUnconsumedCheck = null;
|
|
66353
|
+
this.onUnconsumedEvent(currentEvent);
|
|
66354
|
+
}
|
|
66355
|
+
}, DEFERRED_CHECK_DELAY_MS);
|
|
66356
|
+
});
|
|
66285
66357
|
});
|
|
66286
66358
|
}
|
|
66287
66359
|
}
|
|
66360
|
+
/**
|
|
66361
|
+
* Run `fn` once no data delivery is in flight, polling the way
|
|
66362
|
+
* `scheduleWhenIdle` does: let the promise queue drain, re-check a timer
|
|
66363
|
+
* tick later, repeat.
|
|
66364
|
+
*
|
|
66365
|
+
* Without this the check is a bet that every delivery the walk is running
|
|
66366
|
+
* ahead of lands inside a fixed window. Consumption is synchronous while the
|
|
66367
|
+
* resolution it triggers is not: a step result hydrates in the host, resolves
|
|
66368
|
+
* from a detached continuation behind `awaitEarlierDeliveries`, and only then
|
|
66369
|
+
* does VM code run far enough to subscribe the next consumer. Replaying a
|
|
66370
|
+
* batch of N parallel step results leaves N-1 of them on that detached path
|
|
66371
|
+
* with the queue already drained, so the walk sits on the ordered event the
|
|
66372
|
+
* VM is about to draw and the window is the only thing standing between a
|
|
66373
|
+
* healthy run and `ReplayDivergenceError`. On a backend whose deliveries take
|
|
66374
|
+
* longer than the window, that bet loses.
|
|
66375
|
+
*
|
|
66376
|
+
* Termination is `hasParkedCommittedDelivery`'s: it counts only deliveries
|
|
66377
|
+
* that resolve on their own, so nothing here can gate its own retirement. A
|
|
66378
|
+
* genuinely orphaned event has no delivery to wait on and reaches `fn` on the
|
|
66379
|
+
* first poll.
|
|
66380
|
+
*/
|
|
66381
|
+
whenDeliveryIdle(checkVersion, fn) {
|
|
66382
|
+
const poll = /* @__PURE__ */ __name(() => {
|
|
66383
|
+
this.pendingUnconsumedTimeout = null;
|
|
66384
|
+
if (this.unconsumedCheckVersion !== checkVersion) {
|
|
66385
|
+
return;
|
|
66386
|
+
}
|
|
66387
|
+
if (this.isDeliveryIdle()) {
|
|
66388
|
+
fn();
|
|
66389
|
+
return;
|
|
66390
|
+
}
|
|
66391
|
+
this.getPromiseQueue().then(() => {
|
|
66392
|
+
if (this.unconsumedCheckVersion !== checkVersion) {
|
|
66393
|
+
return;
|
|
66394
|
+
}
|
|
66395
|
+
this.pendingUnconsumedTimeout = setTimeout(poll, 0);
|
|
66396
|
+
});
|
|
66397
|
+
}, "poll");
|
|
66398
|
+
poll();
|
|
66399
|
+
}
|
|
66288
66400
|
};
|
|
66289
66401
|
|
|
66290
66402
|
// ../core/dist/runtime/get-port-lazy.js
|
|
@@ -66411,6 +66523,9 @@ function createUseStep(ctx) {
|
|
|
66411
66523
|
}
|
|
66412
66524
|
if (event.eventType === "step_failed") {
|
|
66413
66525
|
ctx.invocationsQueue.delete(event.correlationId);
|
|
66526
|
+
const eventIndex = ctx.eventsConsumer.eventIndex;
|
|
66527
|
+
const barrier = registerDeliveryBarrier(ctx, eventIndex, "step");
|
|
66528
|
+
const earlierDelivered = awaitEarlierDeliveries(ctx, eventIndex, "step");
|
|
66414
66529
|
ctx.promiseQueue = ctx.promiseQueue.then(() => {
|
|
66415
66530
|
const errorData = event.eventData.error;
|
|
66416
66531
|
const isErrorObject = typeof errorData === "object" && errorData !== null;
|
|
@@ -66420,7 +66535,10 @@ function createUseStep(ctx) {
|
|
|
66420
66535
|
if (errorStack) {
|
|
66421
66536
|
error48.stack = errorStack;
|
|
66422
66537
|
}
|
|
66423
|
-
|
|
66538
|
+
void earlierDelivered.then(() => {
|
|
66539
|
+
barrier.markDelivered();
|
|
66540
|
+
reject(error48);
|
|
66541
|
+
});
|
|
66424
66542
|
});
|
|
66425
66543
|
return EventConsumerResult.Finished;
|
|
66426
66544
|
}
|
|
@@ -66428,16 +66546,28 @@ function createUseStep(ctx) {
|
|
|
66428
66546
|
ctx.invocationsQueue.delete(event.correlationId);
|
|
66429
66547
|
const completedEventId = event.eventId;
|
|
66430
66548
|
const serializedResult = event.eventData.result;
|
|
66549
|
+
const eventIndex = ctx.eventsConsumer.eventIndex;
|
|
66550
|
+
const barrier = registerDeliveryBarrier(ctx, eventIndex, "step");
|
|
66551
|
+
let outcome;
|
|
66552
|
+
const earlierDelivered = awaitEarlierDeliveries(ctx, eventIndex, "step");
|
|
66431
66553
|
ctx.pendingDeliveries++;
|
|
66432
66554
|
ctx.promiseQueue = ctx.promiseQueue.then(async () => {
|
|
66433
66555
|
try {
|
|
66434
66556
|
const hydratedResult = await getOrHydrateStepReturnValue(ctx.stepHydrationCache, completedEventId, () => hydrateStepReturnValue(serializedResult, ctx.runId, ctx.encryptionKey, ctx.globalThis));
|
|
66435
|
-
|
|
66557
|
+
outcome = { ok: true, value: hydratedResult };
|
|
66436
66558
|
} catch (error48) {
|
|
66437
|
-
|
|
66559
|
+
outcome = { ok: false, error: error48 };
|
|
66438
66560
|
} finally {
|
|
66439
66561
|
ctx.pendingDeliveries--;
|
|
66440
66562
|
}
|
|
66563
|
+
void earlierDelivered.then(() => {
|
|
66564
|
+
barrier.markDelivered();
|
|
66565
|
+
if (outcome.ok) {
|
|
66566
|
+
resolve3(outcome.value);
|
|
66567
|
+
} else {
|
|
66568
|
+
reject(outcome.error);
|
|
66569
|
+
}
|
|
66570
|
+
});
|
|
66441
66571
|
});
|
|
66442
66572
|
return EventConsumerResult.Finished;
|
|
66443
66573
|
}
|
|
@@ -66911,10 +67041,10 @@ function createContext(options) {
|
|
|
66911
67041
|
g.Math.random = rng;
|
|
66912
67042
|
const Date_ = g.Date;
|
|
66913
67043
|
g.Date = /* @__PURE__ */ __name(function Date2(...args) {
|
|
66914
|
-
if (
|
|
66915
|
-
return new Date_(fixedTimestamp);
|
|
67044
|
+
if (new.target === void 0) {
|
|
67045
|
+
return new Date_(fixedTimestamp).toString();
|
|
66916
67046
|
}
|
|
66917
|
-
return
|
|
67047
|
+
return Reflect.construct(Date_, args.length === 0 ? [fixedTimestamp] : args, new.target);
|
|
66918
67048
|
}, "Date");
|
|
66919
67049
|
g.Date.prototype = Date_.prototype;
|
|
66920
67050
|
Object.setPrototypeOf(g.Date, Date_);
|
|
@@ -67118,8 +67248,12 @@ function createCreateHook(ctx) {
|
|
|
67118
67248
|
}
|
|
67119
67249
|
if (event.eventType === "hook_received") {
|
|
67120
67250
|
const eventIndex = ctx.eventsConsumer.eventIndex;
|
|
67121
|
-
const
|
|
67122
|
-
|
|
67251
|
+
const hasWaitingConsumer = promises.length > 0;
|
|
67252
|
+
const barrier = registerDeliveryBarrier(ctx, eventIndex, "hook", {
|
|
67253
|
+
armed: hasWaitingConsumer
|
|
67254
|
+
});
|
|
67255
|
+
if (hasWaitingConsumer) {
|
|
67256
|
+
const earlierDelivered = awaitEarlierDeliveries(ctx, eventIndex, "hook");
|
|
67123
67257
|
const next2 = promises.shift();
|
|
67124
67258
|
if (next2) {
|
|
67125
67259
|
ctx.pendingDeliveries++;
|
|
@@ -67133,7 +67267,7 @@ function createCreateHook(ctx) {
|
|
|
67133
67267
|
} finally {
|
|
67134
67268
|
ctx.pendingDeliveries--;
|
|
67135
67269
|
}
|
|
67136
|
-
void
|
|
67270
|
+
void earlierDelivered.then(() => {
|
|
67137
67271
|
barrier.markDelivered();
|
|
67138
67272
|
if (hydrateOutcome.ok) {
|
|
67139
67273
|
next2.resolve(hydrateOutcome.value);
|
|
@@ -67146,13 +67280,16 @@ function createCreateHook(ctx) {
|
|
|
67146
67280
|
} else {
|
|
67147
67281
|
let outcome;
|
|
67148
67282
|
const hydrated = withResolvers();
|
|
67149
|
-
const claim = /* @__PURE__ */ __name(() =>
|
|
67150
|
-
barrier.
|
|
67151
|
-
|
|
67152
|
-
|
|
67153
|
-
|
|
67154
|
-
|
|
67155
|
-
|
|
67283
|
+
const claim = /* @__PURE__ */ __name(() => {
|
|
67284
|
+
barrier.arm();
|
|
67285
|
+
return hydrated.promise.then(() => awaitEarlierDeliveries(ctx, eventIndex, "hook")).then(() => {
|
|
67286
|
+
barrier.markDelivered();
|
|
67287
|
+
if (outcome && !outcome.ok) {
|
|
67288
|
+
throw outcome.error;
|
|
67289
|
+
}
|
|
67290
|
+
return outcome.value;
|
|
67291
|
+
});
|
|
67292
|
+
}, "claim");
|
|
67156
67293
|
ctx.pendingDeliveries++;
|
|
67157
67294
|
ctx.promiseQueue = ctx.promiseQueue.then(async () => {
|
|
67158
67295
|
try {
|
|
@@ -67331,8 +67468,9 @@ function createSleep(ctx) {
|
|
|
67331
67468
|
ctx.invocationsQueue.delete(correlationId);
|
|
67332
67469
|
const eventIndex = ctx.eventsConsumer.eventIndex;
|
|
67333
67470
|
const barrier = registerDeliveryBarrier(ctx, eventIndex, "wait");
|
|
67471
|
+
const earlierDelivered = awaitEarlierDeliveries(ctx, eventIndex, "wait");
|
|
67334
67472
|
const queueAtCompletion = ctx.promiseQueue;
|
|
67335
|
-
void queueAtCompletion.then(() =>
|
|
67473
|
+
void queueAtCompletion.then(() => earlierDelivered).then(() => {
|
|
67336
67474
|
barrier.markDelivered();
|
|
67337
67475
|
resolve3();
|
|
67338
67476
|
});
|
|
@@ -67390,6 +67528,7 @@ async function runWorkflow(workflowCode2, workflowRun, events, encryptionKey, st
|
|
|
67390
67528
|
const ulid5 = monotonicFactory(() => vmGlobalThis.Math.random());
|
|
67391
67529
|
const generateNanoid = customRandom(urlAlphabet, 21, (size) => new Uint8Array(size).map(() => 256 * vmGlobalThis.Math.random()));
|
|
67392
67530
|
const promiseQueueHolder = { current: Promise.resolve() };
|
|
67531
|
+
const deliveryIdleHolder = { current: /* @__PURE__ */ __name(() => true, "current") };
|
|
67393
67532
|
const eventsConsumer = new EventsConsumer(events, {
|
|
67394
67533
|
onConsumedEvent: /* @__PURE__ */ __name((event) => {
|
|
67395
67534
|
updateTimestamp(+event.createdAt);
|
|
@@ -67397,7 +67536,8 @@ async function runWorkflow(workflowCode2, workflowRun, events, encryptionKey, st
|
|
|
67397
67536
|
onUnconsumedEvent: /* @__PURE__ */ __name((event) => {
|
|
67398
67537
|
workflowDiscontinuation.reject(new ReplayDivergenceError(`Replay could not consume event: eventType=${event.eventType}, correlationId=${event.correlationId}, eventId=${event.eventId}.`, { eventId: event.eventId }));
|
|
67399
67538
|
}, "onUnconsumedEvent"),
|
|
67400
|
-
getPromiseQueue: /* @__PURE__ */ __name(() => promiseQueueHolder.current, "getPromiseQueue")
|
|
67539
|
+
getPromiseQueue: /* @__PURE__ */ __name(() => promiseQueueHolder.current, "getPromiseQueue"),
|
|
67540
|
+
isDeliveryIdle: /* @__PURE__ */ __name(() => deliveryIdleHolder.current(), "isDeliveryIdle")
|
|
67401
67541
|
});
|
|
67402
67542
|
const workflowContext = {
|
|
67403
67543
|
runId: workflowRun.runId,
|
|
@@ -67420,6 +67560,7 @@ async function runWorkflow(workflowCode2, workflowRun, events, encryptionKey, st
|
|
|
67420
67560
|
pendingDeliveryBarriers: /* @__PURE__ */ new Map(),
|
|
67421
67561
|
stepHydrationCache
|
|
67422
67562
|
};
|
|
67563
|
+
deliveryIdleHolder.current = () => isDeliveryIdle(workflowContext);
|
|
67423
67564
|
workflowContext.eventsConsumer.subscribe((event) => {
|
|
67424
67565
|
if (!event) {
|
|
67425
67566
|
return EventConsumerResult.NotConsumed;
|