@@ -13,6 +13,7 @@ import {
1313 useContext
1414} from "./reactive.js" ;
1515import type { JSX } from "../jsx.js" ;
16+ import { inspect } from "util" ;
1617
1718export type Component < P = { } > = ( props : P ) => JSX . Element ;
1819export type VoidProps < P = { } > = P & { children ?: never } ;
@@ -435,7 +436,6 @@ export function createResource<T, S>(
435436 fetcher = source as ResourceFetcher < S , T > ;
436437 source = true as ResourceSource < S > ;
437438 }
438-
439439 const contexts = new Set < SuspenseContextType > ( ) ;
440440 const id = sharedConfig . getNextContextId ( ) ;
441441 let resource : { ref ?: any ; data ?: T } = { } ;
@@ -494,7 +494,51 @@ export function createResource<T, S>(
494494 if ( lookup == null || lookup === false ) return ;
495495 p = ( fetcher as ResourceFetcher < S , T > ) ( lookup , { value } ) ;
496496 }
497- if ( p != undefined && typeof p === "object" && "then" in p ) {
497+
498+ const handleResolvedValue = (
499+ p : T | Promise < T > | null ,
500+ ctx : {
501+ id ?: string ;
502+ count ?: number ;
503+ serialize : any ;
504+ nextRoot ?: ( v : any ) => string ;
505+ replace ?: ( id : string , replacement : ( ) => any ) => void ;
506+ block ?: ( p : Promise < any > ) => void ;
507+ resources : any ;
508+ suspense ?: Record < string , SuspenseContextType > ;
509+ registerFragment ?: ( v : string ) => ( v ?: string , err ?: any ) => boolean ;
510+ lazy ?: Record < string , Promise < any > > ;
511+ async ?: boolean | undefined ;
512+ noHydrate ?: boolean ;
513+ } ,
514+ id : string
515+ ) => {
516+ ctx . resources [ id ] . data = p ;
517+ if ( ctx . serialize ) ctx . serialize ( id , p ) ;
518+ p = null ;
519+ return ctx . resources [ id ] . data ;
520+ } ;
521+
522+ if (
523+ p != undefined &&
524+ typeof p === "object" &&
525+ "then" in p &&
526+ p . constructor . name === "Promise"
527+ ) {
528+ if (
529+ lookup === 0 && // 'lookup' of the value returned by createResource
530+ fetcher ! . constructor . name !== "AsyncFunction" &&
531+ ! inspect ( p ) . startsWith ( `Promise {
532+ <pending>,
533+ ` )
534+ ) {
535+ let temp = p ;
536+ p = new Promise ( resolve => {
537+ setTimeout ( ( ) => {
538+ resolve ( temp . then ( val => handleResolvedValue ( val , ctx , id ) ) ) ;
539+ } , 300 ) ; // A safe number that won't throw an error.
540+ } ) ;
541+ }
498542 read . loading = true ;
499543 read . state = "pending" ;
500544 p = p
@@ -517,10 +561,7 @@ export function createResource<T, S>(
517561 if ( ctx . serialize ) ctx . serialize ( id , p , options . deferStream ) ;
518562 return p ;
519563 }
520- ctx . resources [ id ] . data = p ;
521- if ( ctx . serialize ) ctx . serialize ( id , p ) ;
522- p = null ;
523- return ctx . resources [ id ] . data ;
564+ return handleResolvedValue ( p , ctx , id ) ;
524565 }
525566 if ( options . ssrLoadFrom !== "initial" ) load ( ) ;
526567 const ref = [ read , { refetch : load , mutate : ( v : T ) => ( value = v ) } ] as ResourceReturn < T > ;
0 commit comments