@@ -76,37 +76,45 @@ export async function waitForItemQuantityToReach(
7676}
7777
7878/**
79- * Polls the item quantity every 500ms until it stops changing for 8 reads
80- * in a row (~4 seconds of no movement) , then returns the stable value.
81- * Throws if no stable value is observed within 15 seconds .
79+ * Polls the item quantity every 500ms until it stops changing for
80+ * `stableForReads` reads in a row, then returns the stable value. Throws
81+ * if no stable value is observed within `timeoutMs` .
8282 *
8383 * Use this when you DON'T know the exact target — for example, after
8484 * `Auth.Otp.signIn()` triggers an unknown number of async logEvent debits
8585 * (token-refresh + sign-up-rule events) and you just want them to drain
8686 * before measuring a baseline.
8787 *
88- * The 4-second stability window is deliberately conservative: a shorter
89- * one (we tried 1.2s) exits during brief lulls between batches of late-
90- * arriving sign-up-rule debits and lets ~2 extra debits land between the
91- * baseline read and the next test request, breaking exact-quota
92- * assertions.
88+ *
89+ * `options.minimumElapsedMs` (default 0) refuses to return until at least
90+ * that much wall time has passed since the function was called, even if
91+ * the quantity has been stable the whole time. This is useful when the
92+ * caller knows async events should fire but hasn't seen them yet — it
93+ * prevents the function from declaring stability before the async work
94+ * has even started.
9395 */
9496export async function waitForItemQuantityToStabilize (
9597 ownerTeamId : string ,
9698 itemId : ItemId ,
99+ options : { minimumElapsedMs ?: number } = { } ,
97100) : Promise < number > {
98101 const pollIntervalMs = 500 ;
99- const stableForReads = 8 ;
100- const timeoutMs = 15000 ;
102+ const stableForReads = 16 ;
103+ const timeoutMs = 30000 ;
104+ const minimumElapsedMs = options . minimumElapsedMs ?? 0 ;
101105 const startedAt = performance . now ( ) ;
102106
103107 let last = await getItemQuantity ( ownerTeamId , itemId ) ;
104108 let stableReads = 1 ;
105109
106- while ( stableReads < stableForReads ) {
107- if ( performance . now ( ) - startedAt > timeoutMs ) {
110+ while ( true ) {
111+ const elapsed = performance . now ( ) - startedAt ;
112+ if ( stableReads >= stableForReads && elapsed >= minimumElapsedMs ) {
113+ return last ;
114+ }
115+ if ( elapsed > timeoutMs ) {
108116 throw new StackAssertionError ( `Item quantity did not stabilise within timeout` , {
109- ownerTeamId, itemId, last, stableReads, stableForReads, timeoutMs,
117+ ownerTeamId, itemId, last, stableReads, stableForReads, timeoutMs, minimumElapsedMs ,
110118 } ) ;
111119 }
112120
@@ -120,6 +128,4 @@ export async function waitForItemQuantityToStabilize(
120128 last = next ;
121129 }
122130 }
123-
124- return last ;
125131}
0 commit comments