@@ -18,14 +18,16 @@ import {
18
18
update_reaction ,
19
19
increment_write_version ,
20
20
set_active_effect ,
21
- component_context
21
+ component_context ,
22
+ get
22
23
} from '../runtime.js' ;
23
24
import { equals , safe_equals } from './equality.js' ;
24
25
import * as e from '../errors.js' ;
25
- import { destroy_effect } from './effects.js' ;
26
- import { inspect_effects , set_inspect_effects } from './sources.js' ;
26
+ import { destroy_effect , render_effect } from './effects.js' ;
27
+ import { inspect_effects , internal_set , set_inspect_effects , source } from './sources.js' ;
27
28
import { get_stack } from '../dev/tracing.js' ;
28
29
import { tracing_mode_flag } from '../../flags/index.js' ;
30
+ import { preserve_context } from '../dom/blocks/boundary.js' ;
29
31
30
32
/**
31
33
* @template V
@@ -75,6 +77,36 @@ export function derived(fn) {
75
77
return signal ;
76
78
}
77
79
80
+ /**
81
+ * @template V
82
+ * @param {() => Promise<V> } fn
83
+ * @returns {Promise<() => V> }
84
+ */
85
+ /*#__NO_SIDE_EFFECTS__*/
86
+ export async function async_derived ( fn ) {
87
+ if ( ! active_effect ) {
88
+ throw new Error ( 'TODO cannot create unowned async derived' ) ;
89
+ }
90
+
91
+ let promise = /** @type {Promise<V> } */ ( /** @type {unknown } */ ( undefined ) ) ;
92
+ let value = source ( /** @type {V } */ ( undefined ) ) ;
93
+
94
+ render_effect ( ( ) => {
95
+ const current = ( promise = fn ( ) ) ;
96
+
97
+ promise . then ( ( v ) => {
98
+ if ( promise === current ) {
99
+ internal_set ( value , v ) ;
100
+ }
101
+ } ) ;
102
+
103
+ // TODO what happens when the promise rejects?
104
+ } ) ;
105
+
106
+ ( await preserve_context ( promise ) ) . read ( ) ;
107
+ return ( ) => get ( value ) ;
108
+ }
109
+
78
110
/**
79
111
* @template V
80
112
* @param {() => V } fn
0 commit comments