22globalThis . IS_REACT_ACT_ENVIRONMENT = true ;
33
44import { createElement , lazy , useLayoutEffect , Suspense } from "react" ;
5- import { signal } from "@preact/signals-core" ;
5+ import { signal , Signal } from "@preact/signals-core" ;
66import {
77 useComputed ,
88 useSignalEffect ,
@@ -20,6 +20,7 @@ import { beforeEach, afterEach, describe, it, expect } from "vitest";
2020describe ( "Suspense" , ( ) => {
2121 let scratch : HTMLDivElement ;
2222 let root : Root ;
23+ let originalSubscribe : typeof Signal . prototype . _subscribe ;
2324
2425 async function render ( element : Parameters < Root [ "render" ] > [ 0 ] ) {
2526 await act ( ( ) => root . render ( element ) ) ;
@@ -30,6 +31,7 @@ describe("Suspense", () => {
3031 document . body . appendChild ( scratch ) ;
3132 root = await createRoot ( scratch ) ;
3233 getConsoleErrorSpy ( ) . mockClear ( ) ;
34+ originalSubscribe = Signal . prototype . _subscribe ;
3335 } ) ;
3436
3537 afterEach ( async ( ) => {
@@ -41,6 +43,7 @@ describe("Suspense", () => {
4143 //
4244 // checkConsoleErrorLogs();
4345 checkHangingAct ( ) ;
46+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
4447 } ) ;
4548
4649 it ( "should handle suspending and unsuspending" , async ( ) => {
@@ -123,15 +126,19 @@ describe("Suspense", () => {
123126 signal1 . value ++ ;
124127 signal2 . value ++ ;
125128 } ) ;
129+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
130+
126131 await act ( async ( ) => {
127132 signal1 . value -- ;
128133 signal2 . value -- ;
129134 } ) ;
135+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
130136
131137 await act ( async ( ) => {
132138 resolveMiddleProm ( ) ;
133139 await middleProm ;
134140 } ) ;
141+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
135142
136143 expect ( scratch . innerHTML ) . to . be . oneOf ( [
137144 // react 17+
@@ -144,6 +151,7 @@ describe("Suspense", () => {
144151 unsuspend ( ) ;
145152 await prom ;
146153 } ) ;
154+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
147155
148156 // react 16 uses `style.setProperty()` to clear display value, which leaves an empty style attr in innerHTML.
149157 // react 17 does not do this, so we normalize 16 behavior to 17 here.
@@ -158,6 +166,8 @@ describe("Suspense", () => {
158166 signal1 . value ++ ;
159167 signal2 . value ++ ;
160168 } ) ;
169+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
170+
161171 expect ( scratch . innerHTML ) . to . equal (
162172 `<p>1</p><div data-foo="1"><span>lazy</span></div>`
163173 ) ;
@@ -237,6 +247,7 @@ describe("Suspense", () => {
237247
238248 // Initial render - should trigger watched callback
239249 await render ( < Parent /> ) ;
250+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
240251 expect ( scratch . innerHTML ) . to . contain ( "Loading first..." ) ;
241252 expect ( scratch . innerHTML ) . to . contain ( "Loading second..." ) ;
242253 expect ( scratch . innerHTML ) . to . contain ( "Regular" ) ;
@@ -250,6 +261,7 @@ describe("Suspense", () => {
250261 resolveFirstProm ( ) ;
251262 await firstProm ;
252263 } ) ;
264+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
253265
254266 expect ( scratch . innerHTML ) . to . contain ( "First" ) ;
255267 expect ( scratch . innerHTML ) . to . contain ( "Loading second..." ) ;
@@ -259,6 +271,7 @@ describe("Suspense", () => {
259271 resolveSecondProm ( ) ;
260272 await secondProm ;
261273 } ) ;
274+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
262275
263276 expect ( scratch . innerHTML ) . to . contain ( "First" ) ;
264277 expect ( scratch . innerHTML ) . to . contain ( "Second" ) ;
@@ -268,6 +281,7 @@ describe("Suspense", () => {
268281 await act ( async ( ) => {
269282 trackedSignal . value = 42 ;
270283 } ) ;
284+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
271285
272286 expect ( scratch . innerHTML ) . to . contain ( 'data-parent="42"' ) ;
273287 expect ( scratch . innerHTML ) . to . contain ( 'data-regular="42"' ) ;
@@ -282,7 +296,7 @@ describe("Suspense", () => {
282296 expect ( scratch . innerHTML ) . to . equal ( "" ) ;
283297
284298 // Wait for cleanup to complete
285- await new Promise ( resolve => setTimeout ( resolve , 10 ) ) ;
299+ await new Promise ( resolve => setTimeout ( resolve , 100 ) ) ;
286300
287301 // After unmount, the signal should be unwatched
288302 expect ( unwatchedCallCount ) . to . be . greaterThan ( 0 ) ;
@@ -386,6 +400,7 @@ describe("Suspense", () => {
386400
387401 // Initial render - should trigger watched callback
388402 await render ( < Parent /> ) ;
403+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
389404 expect ( scratch . innerHTML ) . to . contain ( "Loading first..." ) ;
390405 expect ( scratch . innerHTML ) . to . contain ( "Loading second..." ) ;
391406 expect ( scratch . innerHTML ) . to . contain ( "Regular" ) ;
@@ -400,6 +415,7 @@ describe("Suspense", () => {
400415 await firstProm ;
401416 } ) ;
402417
418+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
403419 expect ( scratch . innerHTML ) . to . contain ( "First" ) ;
404420 expect ( scratch . innerHTML ) . to . contain ( "Loading second..." ) ;
405421
@@ -409,6 +425,7 @@ describe("Suspense", () => {
409425 await secondProm ;
410426 } ) ;
411427
428+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
412429 expect ( scratch . innerHTML ) . to . contain ( "First" ) ;
413430 expect ( scratch . innerHTML ) . to . contain ( "Second" ) ;
414431 expect ( scratch . innerHTML ) . to . contain ( "Regular" ) ;
@@ -418,6 +435,7 @@ describe("Suspense", () => {
418435 trackedSignal . value = 42 ;
419436 } ) ;
420437
438+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
421439 expect ( scratch . innerHTML ) . to . contain ( 'data-parent="42"' ) ;
422440 expect ( scratch . innerHTML ) . to . contain ( 'data-regular="42"' ) ;
423441 expect ( scratch . innerHTML ) . to . contain ( 'data-first="42"' ) ;
@@ -428,10 +446,11 @@ describe("Suspense", () => {
428446 root . unmount ( ) ;
429447 } ) ;
430448
449+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
431450 expect ( scratch . innerHTML ) . to . equal ( "" ) ;
432451
433452 // Wait for cleanup to complete
434- await new Promise ( resolve => setTimeout ( resolve , 10 ) ) ;
453+ await new Promise ( resolve => setTimeout ( resolve , 100 ) ) ;
435454
436455 // After unmount, the signal should be unwatched
437456 expect ( unwatchedCallCount ) . to . be . greaterThan ( 0 ) ;
@@ -479,6 +498,7 @@ describe("Suspense", () => {
479498
480499 // Initial render - should trigger watched callback
481500 await render ( < Parent /> ) ;
501+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
482502 expect ( scratch . innerHTML ) . to . contain ( "Regular" ) ;
483503
484504 // Signal should be watched by now
@@ -489,6 +509,7 @@ describe("Suspense", () => {
489509 await act ( async ( ) => {
490510 trackedSignal . value = 10 ;
491511 } ) ;
512+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
492513
493514 expect ( scratch . innerHTML ) . to . contain ( 'data-parent="10"' ) ;
494515 expect ( scratch . innerHTML ) . to . contain ( 'data-regular="10"' ) ;
@@ -498,6 +519,7 @@ describe("Suspense", () => {
498519 trackedSignal . value = 20 ;
499520 } ) ;
500521
522+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
501523 expect ( scratch . innerHTML ) . to . contain ( 'data-parent="20"' ) ;
502524 expect ( scratch . innerHTML ) . to . contain ( 'data-regular="20"' ) ;
503525
@@ -509,10 +531,11 @@ describe("Suspense", () => {
509531 root . unmount ( ) ;
510532 } ) ;
511533
534+ expect ( Signal . prototype . _subscribe ) . to . equal ( originalSubscribe ) ;
512535 expect ( scratch . innerHTML ) . to . equal ( "" ) ;
513536
514537 // Wait for cleanup to complete
515- await new Promise ( resolve => setTimeout ( resolve , 10 ) ) ;
538+ await new Promise ( resolve => setTimeout ( resolve , 100 ) ) ;
516539
517540 // After unmount, the signal should be unwatched
518541 expect ( unwatchedCallCount ) . to . be . greaterThan ( 0 ) ;
0 commit comments