MCPcopy
hub / github.com/SBoudrias/Inquirer.js / next

Method next

packages/testing/src/screen.ts:63–118  ·  view source on GitHub ↗

* Wait for the next screen update. * * Handles re-renders within the same prompt (e.g., validation errors, * async updates) and prompt transitions in multi-prompt flows * (automatically waits for the next prompt). * * Note: The initial prompt render is available immediately via get

()

Source from the content-addressed store, hash-verified

61 * — no next() call is needed before reading it.
62 */
63 async next(): Promise<void> {
64 if (this.#activePromise) {
65 const currentPromise = this.#activePromise;
66
67 // Consume any renders that happened synchronously (e.g., loading state).
68 // We want to wait for the next meaningful state change, not an intermediate render.
69 this.#rendersConsumed = this.#currentOutput?.writeCount ?? 0;
70
71 // Race: a future render (validation error, async update) vs the promise settling
72 // (prompt completed, possibly synchronously before any new render arrives).
73 const renderPromise = this.#waitForNextRender();
74 const settlePromise = currentPromise.then(
75 () => 'settled' as const,
76 () => 'settled' as const,
77 );
78
79 const result = await Promise.race([
80 renderPromise.then(() => 'render' as const),
81 settlePromise,
82 ]);
83
84 if (result === 'settled') {
85 if (this.#activePromise !== currentPromise) {
86 // New prompt already started — its render was caught by the race's renderPromise.
87 this.#rendersConsumed = this.#currentOutput?.writeCount ?? 0;
88 } else {
89 // Prompt settled but no new prompt yet. Wait for the next prompt's first render.
90 await this.#waitForNextRender();
91 }
92 } else {
93 // Got a render. Check if the prompt also completed (making this a "done" render).
94 // Microtasks (promise settlement) always drain before macrotasks (setImmediate),
95 // so if the prompt resolved, its .then wins the race.
96 const settled = await Promise.race([
97 currentPromise.then(
98 () => true,
99 () => true,
100 ),
101 new Promise<false>((resolve) => setImmediate(() => resolve(false))),
102 ]);
103
104 if (settled) {
105 if (this.#activePromise !== currentPromise) {
106 // New prompt already started — its render was caught by the race.
107 this.#rendersConsumed = this.#currentOutput?.writeCount ?? 0;
108 } else {
109 // Prompt completed but no new prompt yet. Wait for it.
110 await this.#waitForNextRender();
111 }
112 }
113 }
114 } else {
115 // No active promise — wait for a render (e.g., prompt hasn't started yet)
116 await this.#waitForNextRender();
117 }
118 }
119
120 async #waitForNextRender(): Promise<void> {

Callers 1

demo.test.tsFile · 0.45

Calls 1

#waitForNextRenderMethod · 0.95

Tested by

no test coverage detected