chore(deps): Update xstate to v5.32.4#333
Conversation
e3790c6 to
6e13ead
Compare
|
I validated a non-blocking ordering regression in What the repro shows
jest.mocked(spawnInteractive).mockReturnValue({
actions: {
write: jest.fn(),
writeLine: jest.fn(),
stop: jest.fn(),
},
exitCode: Promise.resolve(0),
});
const states: string[] = [];
await cli.deploy({}, (state) => states.push(state.type));
expect(states).toEqual(["running"]);On this PR head, the assertion fails with This is technically an observable behavior regression from v4, but normal Terraform apply/destroy invocations emit stdout/stderr. Those events produce a later snapshot while the machine is still in So I see this as a non-blocking lifecycle hardening opportunity, rather than evidence of a current customer-facing failure. The practical difference for a real Terraform run is that Minimal fix validated locallyProcessing the actor's current snapshot once after subscribing restores the initial callback without changing the factory API: const handleSnapshot = (
snapshot: ReturnType<typeof service.getSnapshot>,
) => {
// existing transition handling
};
service.subscribe(handleSnapshot);
// The actor was already started by createService, so consume the
// snapshot whose transition may have preceded the subscription.
handleSnapshot(service.getSnapshot());I pushed the TDD sequence as two commits:
Branch: https://github.com/sakul-learning/cdk-terrain/tree/review/pr-333-xstate-running-repro Validation:
Given the realistic execution path and green existing CI, this is a suggestion rather than a requested change. |
so0k
left a comment
There was a problem hiding this comment.
Up to you if you want to address the non-block ordering concern (which may not be a real failure mode) - still need to rebase for conflict resolution
Description
Bumps
xstatefrom4.38.3to5.32.4(latest) in@cdktn/cli-core, the only package that declares it.This is a major version bump (4.x → 5.x) and required migrating the deploy state machine, its consumer, and its tests to the reworked v5 API:
createMachine<Ctx, Evt, State>(…)→setup({ types, actors }).createMachine(…). The generic-parameter form was replaced by thesetup()builder with atypesblock, indeploy-machine.ts. ThepredictableActionArgumentsflag was dropped (predictable ordering is the default in v5) andservicesbecameactors.fromCallback. The v4(context, event) => (send, onReceive) => {…}factory becamefromCallback(({ sendBack, receive, input }) => …). Since v5 invoked actors receiveinputrather than the triggering event, the spawn config now flows in throughinvoke.input. The actor is built bymakeTerraformPtyService(spawn)so tests can inject a mock pty.send(…, { to })→sendTo(…);assign<Ctx, Evt>→assign. Action creators were split and theassignimplementation signature changed to a single argument.raise(…)→sendTo(({ self }) => self, …). The two internally re-emitted events (EXITEDon a missing variable, and theOVERRIDE_REJECTED_EXTERNALLYre-label of an external discard) were sent to self rather than raised. Raised events are internal micro-steps and do not surface through the inspection API, so the consumer would otherwise stop observing them.interpret(…)→createActor(…, { inspect }). The actor is now started explicitly before events are sent.The consumer in
terraform-cli.tsneeded the most care, because v5 snapshots no longer expose the triggering event (state.event):service.subscribe(…), which yields a fully-typed snapshot for the root actor only — replacingservice.onTransition(…).inspectcallback (the only source that still carries the triggering event), replacingservice.onEvent(…). The root actor is identified by reference so the invoked pty child's events are ignored, and events are narrowed through the existingisDeployEventguard.EXITEDexit code is now remembered from inspection to decide whether the run failed, since it is no longer readable off the final snapshot.waitForis imported fromxstateand its predicate usessnapshot.status === "done";service.send("X")calls becameservice.send({ type: "X" }).The tests in
deploy-machine.test.tswere migrated to match:interpret().onTransition→createActor().subscribe,withConfig({ services })→provide({ actors }),machine.transition→getNextSnapshot, and thestate.eventassertions rebuilt on the inspection API.Checklist