11import { DEV } from 'esm-env' ;
22import { subscribe_to_store } from '../../store/utils.js' ;
3- import { noop , run_all } from '../common.js' ;
3+ import { noop , run , run_all } from '../common.js' ;
44import {
55 array_prototype ,
66 get_descriptor ,
@@ -104,18 +104,9 @@ export let current_block = null;
104104
105105/** @type {import('./types.js').ComponentContext | null } */
106106export let current_component_context = null ;
107- export let is_ssr = false ;
108107
109108export let updating_derived = false ;
110109
111- /**
112- * @param {boolean } ssr
113- * @returns {void }
114- */
115- export function set_is_ssr ( ssr ) {
116- is_ssr = ssr ;
117- }
118-
119110/**
120111 * @param {null | import('./types.js').ComponentContext } context
121112 * @returns {boolean }
@@ -147,14 +138,6 @@ export function batch_inspect(target, prop, receiver) {
147138 } ;
148139}
149140
150- /**
151- * @param {null | import('./types.js').ComponentContext } context_stack_item
152- * @returns {void }
153- */
154- export function set_current_component_context ( context_stack_item ) {
155- current_component_context = context_stack_item ;
156- }
157-
158141/**
159142 * @param {unknown } a
160143 * @param {unknown } b
@@ -181,8 +164,6 @@ function create_source_signal(flags, value) {
181164 f : flags ,
182165 // value
183166 v : value ,
184- // context: We can remove this if we get rid of beforeUpdate/afterUpdate
185- x : null ,
186167 // this is for DEV only
187168 inspect : new Set ( )
188169 } ;
@@ -195,9 +176,7 @@ function create_source_signal(flags, value) {
195176 // flags
196177 f : flags ,
197178 // value
198- v : value ,
199- // context: We can remove this if we get rid of beforeUpdate/afterUpdate
200- x : null
179+ v : value
201180 } ;
202181}
203182
@@ -346,12 +325,6 @@ function execute_signal_fn(signal) {
346325 current_skip_consumer = ! is_flushing_effect && ( flags & UNOWNED ) !== 0 ;
347326 current_untracking = false ;
348327
349- // Render effects are invoked when the UI is about to be updated - run beforeUpdate at that point
350- if ( is_render_effect && current_component_context ?. u != null ) {
351- // update_callbacks.execute()
352- current_component_context . u . e ( ) ;
353- }
354-
355328 try {
356329 let res ;
357330 if ( is_render_effect ) {
@@ -924,7 +897,7 @@ export function store_set(store, value) {
924897 * @param {import('./types.js').StoreReferencesContainer } stores
925898 */
926899export function unsubscribe_on_destroy ( stores ) {
927- onDestroy ( ( ) => {
900+ on_destroy ( ( ) => {
928901 let store_name ;
929902 for ( store_name in stores ) {
930903 const ref = stores [ store_name ] ;
@@ -1150,7 +1123,7 @@ export function mark_subtree_inert(signal, inert, visited_blocks = new Set()) {
11501123 * @returns {void }
11511124 */
11521125function mark_signal_consumers ( signal , to_status , force_schedule ) {
1153- const runes = is_runes ( signal . x ) ;
1126+ const runes = is_runes ( null ) ;
11541127 const consumers = signal . c ;
11551128 if ( consumers !== null ) {
11561129 const length = consumers . length ;
@@ -1192,7 +1165,7 @@ export function set_signal_value(signal, value) {
11921165 ! current_untracking &&
11931166 ! ignore_mutation_validation &&
11941167 current_consumer !== null &&
1195- is_runes ( signal . x ) &&
1168+ is_runes ( null ) &&
11961169 ( current_consumer . f & DERIVED ) !== 0
11971170 ) {
11981171 throw new Error (
@@ -1208,7 +1181,6 @@ export function set_signal_value(signal, value) {
12081181 ( signal . f & SOURCE ) !== 0 &&
12091182 ! ( /** @type {import('./types.js').EqualsFunctions } */ ( signal . e ) ( value , signal . v ) )
12101183 ) {
1211- const component_context = signal . x ;
12121184 signal . v = value ;
12131185 // If the current signal is running for the first time, it won't have any
12141186 // consumers as we only allocate and assign the consumers after the signal
@@ -1219,7 +1191,7 @@ export function set_signal_value(signal, value) {
12191191 // $effect(() => x++)
12201192 //
12211193 if (
1222- is_runes ( component_context ) &&
1194+ is_runes ( null ) &&
12231195 current_effect !== null &&
12241196 current_effect . c === null &&
12251197 ( current_effect . f & CLEAN ) !== 0
@@ -1236,19 +1208,6 @@ export function set_signal_value(signal, value) {
12361208 }
12371209 }
12381210 mark_signal_consumers ( signal , DIRTY , true ) ;
1239- // If we have afterUpdates locally on the component, but we're within a render effect
1240- // then we will need to manually invoke the beforeUpdate/afterUpdate logic.
1241- // TODO: should we put this being a is_runes check and only run it in non-runes mode?
1242- if ( current_effect === null && current_queued_pre_and_render_effects . length === 0 ) {
1243- const update_callbacks = component_context ?. u ;
1244- if ( update_callbacks != null ) {
1245- run_all ( update_callbacks . b ) ;
1246- const managed = managed_effect ( ( ) => {
1247- destroy_signal ( managed ) ;
1248- run_all ( update_callbacks . a ) ;
1249- } ) ;
1250- }
1251- }
12521211
12531212 // @ts -expect-error
12541213 if ( DEV && signal . inspect ) {
@@ -1299,7 +1258,7 @@ export function derived(init) {
12991258 create_computation_signal ( flags | CLEAN , UNINITIALIZED , current_block )
13001259 ) ;
13011260 signal . i = init ;
1302- signal . x = current_component_context ;
1261+ bind_signal_to_component_context ( signal ) ;
13031262 signal . e = default_equals ;
13041263 if ( current_consumer !== null ) {
13051264 push_reference ( current_consumer , signal ) ;
@@ -1327,10 +1286,27 @@ export function derived_safe_equal(init) {
13271286/*#__NO_SIDE_EFFECTS__*/
13281287export function source ( initial_value ) {
13291288 const source = create_source_signal ( SOURCE | CLEAN , initial_value ) ;
1330- source . x = current_component_context ;
1289+ bind_signal_to_component_context ( source ) ;
13311290 return source ;
13321291}
13331292
1293+ /**
1294+ * This function binds a signal to the component context, so that we can fire
1295+ * beforeUpdate/afterUpdate callbacks at the correct time etc
1296+ * @param {import('./types.js').Signal } signal
1297+ */
1298+ function bind_signal_to_component_context ( signal ) {
1299+ if ( current_component_context === null || ! current_component_context . r ) return ;
1300+
1301+ const signals = current_component_context . d ;
1302+
1303+ if ( signals ) {
1304+ signals . push ( signal ) ;
1305+ } else {
1306+ current_component_context . d = [ signal ] ;
1307+ }
1308+ }
1309+
13341310/**
13351311 * @template V
13361312 * @param {V } initial_value
@@ -1883,18 +1859,11 @@ export function value_or_fallback(value, fallback) {
18831859
18841860/**
18851861 * Schedules a callback to run immediately before the component is unmounted.
1886- *
1887- * Out of `onMount`, `beforeUpdate`, `afterUpdate` and `onDestroy`, this is the
1888- * only one that runs inside a server-side component.
1889- *
1890- * https://svelte.dev/docs/svelte#ondestroy
18911862 * @param {() => any } fn
18921863 * @returns {void }
18931864 */
1894- export function onDestroy ( fn ) {
1895- if ( ! is_ssr ) {
1896- user_effect ( ( ) => ( ) => untrack ( fn ) ) ;
1897- }
1865+ function on_destroy ( fn ) {
1866+ user_effect ( ( ) => ( ) => untrack ( fn ) ) ;
18981867}
18991868
19001869/**
@@ -1914,6 +1883,8 @@ export function push(props, runes = false) {
19141883 m : false ,
19151884 // parent
19161885 p : current_component_context ,
1886+ // signals
1887+ d : null ,
19171888 // props
19181889 s : props ,
19191890 // runes
@@ -1945,6 +1916,56 @@ export function pop(accessors) {
19451916 }
19461917}
19471918
1919+ /**
1920+ * Invoke the getter of all signals associated with a component
1921+ * so they can be registered to the effect this function is called in.
1922+ * @param {import('./types.js').ComponentContext } context
1923+ */
1924+ function observe_all ( context ) {
1925+ if ( context . d ) {
1926+ for ( const signal of context . d ) get ( signal ) ;
1927+ }
1928+
1929+ const props = get_descriptors ( context . s ) ;
1930+ for ( const descriptor of Object . values ( props ) ) {
1931+ if ( descriptor . get ) descriptor . get ( ) ;
1932+ }
1933+ }
1934+
1935+ /**
1936+ * Legacy-mode only: Call `onMount` callbacks and set up `beforeUpdate`/`afterUpdate` effects
1937+ */
1938+ export function init ( ) {
1939+ const context = /** @type {import('./types.js').ComponentContext } */ ( current_component_context ) ;
1940+ const callbacks = context . u ;
1941+
1942+ if ( ! callbacks ) return ;
1943+
1944+ // beforeUpdate
1945+ pre_effect ( ( ) => {
1946+ observe_all ( context ) ;
1947+ callbacks . b . forEach ( run ) ;
1948+ } ) ;
1949+
1950+ // onMount (must run before afterUpdate)
1951+ user_effect ( ( ) => {
1952+ const fns = untrack ( ( ) => callbacks . m . map ( run ) ) ;
1953+ return ( ) => {
1954+ for ( const fn of fns ) {
1955+ if ( typeof fn === 'function' ) {
1956+ fn ( ) ;
1957+ }
1958+ }
1959+ } ;
1960+ } ) ;
1961+
1962+ // afterUpdate
1963+ user_effect ( ( ) => {
1964+ observe_all ( context ) ;
1965+ callbacks . a . forEach ( run ) ;
1966+ } ) ;
1967+ }
1968+
19481969/**
19491970 * @param {any } value
19501971 * @param {Set<any> } visited
0 commit comments