@ -1,9 +1,7 @@
import { DEV } from 'esm-env' ;
import { subscribe _to _store } from '../../store/utils.js' ;
import { noop , run , run _all } from '../common.js' ;
import { run _all } from '../common.js' ;
import {
array _prototype ,
get _descriptor ,
get _descriptors ,
get _prototype _of ,
is _array ,
@ -11,41 +9,37 @@ import {
object _freeze ,
object _prototype
} from './utils.js' ;
import { unstate } from './proxy.js' ;
import { pre _effect } from './reactivity/computations.js' ;
import {
PROPS _IS _LAZY _INITIAL ,
PROPS _IS _IMMUTABLE ,
PROPS _IS _RUNES ,
PROPS _IS _UPDATED
} from '../../constants.js' ;
import { STATE _SYMBOL , unstate } from './proxy.js' ;
import { EACH _BLOCK , IF _BLOCK } from './block.js' ;
export const SOURCE = 1 ;
export const DERIVED = 1 << 1 ;
export const EFFECT = 1 << 2 ;
export const PRE _EFFECT = 1 << 3 ;
export const RENDER _EFFECT = 1 << 4 ;
const MANAGED = 1 << 6 ;
const UNOWNED = 1 << 7 ;
export const CLEAN = 1 << 8 ;
export const DIRTY = 1 << 9 ;
export const MAYBE _DIRTY = 1 << 10 ;
export const INERT = 1 << 11 ;
export const DESTROYED = 1 << 12 ;
EACH _BLOCK ,
IF _BLOCK ,
EFFECT ,
PRE _EFFECT ,
RENDER _EFFECT ,
DIRTY ,
UNINITIALIZED ,
MAYBE _DIRTY ,
CLEAN ,
DERIVED ,
UNOWNED ,
DESTROYED ,
INERT ,
MANAGED ,
SOURCE ,
STATE _SYMBOL
} from './constants.js' ;
import { flush _tasks } from './dom/task.js' ;
const IS _EFFECT = EFFECT | PRE _EFFECT | RENDER _EFFECT ;
const FLUSH _MICROTASK = 0 ;
const FLUSH _SYNC = 1 ;
export const UNINITIALIZED = Symbol ( ) ;
// Used for controlling the flush of effects.
let current _scheduler _mode = FLUSH _MICROTASK ;
// Used for handling scheduling
let is _micro _task _queued = false ;
let is _task _queued = false ;
let is _raf _queued = false ;
let is _flushing _effect = false ;
// Used for $inspect
export let is _batching _effect = false ;
@ -58,15 +52,11 @@ let current_queued_pre_and_render_effects = [];
/** @type {import('./types.js').EffectSignal[]} */
let current _queued _effects = [ ] ;
/** @type {Array<() => void>} */
let current _queued _tasks = [ ] ;
/** @type {Array<() => void>} */
let current _raf _tasks = [ ] ;
let flush _count = 0 ;
// Handle signal reactivity tree dependencies and consumer
/** @type {null | import('./types.js').ComputationSignal} */
let current _consumer = null ;
export let current _consumer = null ;
/** @type {null | import('./types.js').EffectSignal} */
export let current _effect = null ;
@ -86,16 +76,20 @@ let last_inspected_signal = null;
export let current _untracking = false ;
/** Exists to opt out of the mutation validation for stores which may be set for the first time during a derivation */
let ignore _mutation _validation = false ;
/** @param {boolean} value */
export function set _ignore _mutation _validation ( value ) {
ignore _mutation _validation = value ;
}
// If we are working with a get() chain that has no active container,
// to prevent memory leaks, we skip adding the consumer.
let current _skip _consumer = false ;
// Handle collecting all signals which are read during a specific time frame
let is _signals _recorded = false ;
export let is _signals _recorded = false ;
let captured _signals = new Set ( ) ;
/** @type {Function | null} */
let inspect _fn = null ;
export let inspect _fn = null ;
/** @type {Array<import('./types.js').SignalDebug>} */
let inspect _captured _signals = [ ] ;
@ -144,133 +138,6 @@ export function batch_inspect(target, prop, receiver) {
} ;
}
/ * *
* @ param { unknown } a
* @ param { unknown } b
* @ returns { boolean }
* /
export function default _equals ( a , b ) {
return a === b ;
}
/ * *
* @ template V
* @ param { import ( './types.js' ) . SignalFlags } flags
* @ param { V } value
* @ returns { import ( './types.js' ) . SourceSignal < V > | import ( './types.js' ) . SourceSignal < V > & import ( './types.js' ) . SourceSignalDebug }
* /
function create _source _signal ( flags , value ) {
if ( DEV ) {
return {
// consumers
c : null ,
// equals
e : default _equals ,
// flags
f : flags ,
// value
v : value ,
// write version
w : 0 ,
// this is for DEV only
inspect : new Set ( )
} ;
}
return {
// consumers
c : null ,
// equals
e : default _equals ,
// flags
f : flags ,
// value
v : value ,
// write version
w : 0
} ;
}
/ * *
* @ template V
* @ param { import ( './types.js' ) . SignalFlags } flags
* @ param { V } value
* @ param { import ( './types.js' ) . Block | null } block
* @ returns { import ( './types.js' ) . ComputationSignal < V > | import ( './types.js' ) . ComputationSignal < V > & import ( './types.js' ) . SourceSignalDebug }
* /
function create _computation _signal ( flags , value , block ) {
if ( DEV ) {
return {
// block
b : block ,
// consumers
c : null ,
// destroy
d : null ,
// equals
e : null ,
// flags
f : flags ,
// init
i : null ,
// level
l : 0 ,
// references
r : null ,
// value
v : value ,
// write version
w : 0 ,
// context: We can remove this if we get rid of beforeUpdate/afterUpdate
x : null ,
// destroy
y : null ,
// this is for DEV only
inspect : new Set ( )
} ;
}
return {
// block
b : block ,
// consumers
c : null ,
// destroy
d : null ,
// equals
e : null ,
// flags
f : flags ,
// level
l : 0 ,
// init
i : null ,
// references
r : null ,
// value
v : value ,
// write version
w : 0 ,
// context: We can remove this if we get rid of beforeUpdate/afterUpdate
x : null ,
// destroy
y : null
} ;
}
/ * *
* @ param { import ( './types.js' ) . ComputationSignal } target _signal
* @ param { import ( './types.js' ) . ComputationSignal } ref _signal
* @ returns { void }
* /
function push _reference ( target _signal , ref _signal ) {
const references = target _signal . r ;
if ( references === null ) {
target _signal . r = [ ref _signal ] ;
} else {
references . push ( ref _signal ) ;
}
}
/ * *
* @ template V
* @ param { import ( './types.js' ) . Signal < V > } signal
@ -694,44 +561,6 @@ export function schedule_effect(signal, sync) {
}
}
function process _task ( ) {
is _task _queued = false ;
const tasks = current _queued _tasks . slice ( ) ;
current _queued _tasks = [ ] ;
run _all ( tasks ) ;
}
function process _raf _task ( ) {
is _raf _queued = false ;
const tasks = current _raf _tasks . slice ( ) ;
current _raf _tasks = [ ] ;
run _all ( tasks ) ;
}
/ * *
* @ param { ( ) => void } fn
* @ returns { void }
* /
export function schedule _task ( fn ) {
if ( ! is _task _queued ) {
is _task _queued = true ;
setTimeout ( process _task , 0 ) ;
}
current _queued _tasks . push ( fn ) ;
}
/ * *
* @ param { ( ) => void } fn
* @ returns { void }
* /
export function schedule _raf _task ( fn ) {
if ( ! is _raf _queued ) {
is _raf _queued = true ;
requestAnimationFrame ( process _raf _task ) ;
}
current _raf _tasks . push ( fn ) ;
}
/ * *
* @ returns { void }
* /
@ -807,12 +636,7 @@ export function flush_sync(fn, flush_previous = true) {
if ( current _queued _pre _and _render _effects . length > 0 || effects . length > 0 ) {
flushSync ( ) ;
}
if ( is _raf _queued ) {
process _raf _task ( ) ;
}
if ( is _task _queued ) {
process _task ( ) ;
}
flush _tasks ( ) ;
flush _count = 0 ;
} finally {
current _scheduler _mode = previous _scheduler _mode ;
@ -863,96 +687,6 @@ function update_derived(signal, force_schedule) {
}
}
/ * *
* Gets the current value of a store . If the store isn ' t subscribed to yet , it will create a proxy
* signal that will be updated when the store is . The store references container is needed to
* track reassignments to stores and to track the correct component context .
* @ template V
* @ param { import ( './types.js' ) . Store < V > | null | undefined } store
* @ param { string } store _name
* @ param { import ( './types.js' ) . StoreReferencesContainer } stores
* @ returns { V }
* /
export function store _get ( store , store _name , stores ) {
/** @type {import('./types.js').StoreReferencesContainer[''] | undefined} */
let entry = stores [ store _name ] ;
const is _new = entry === undefined ;
if ( is _new ) {
entry = {
store : null ,
last _value : null ,
value : mutable _source ( UNINITIALIZED ) ,
unsubscribe : noop
} ;
// TODO: can we remove this code? it was refactored out when we split up source/comptued signals
// push_destroy_fn(entry.value, () => {
// /** @type {import('./types.js').StoreReferencesContainer['']} */ (entry).last_value =
// /** @type {import('./types.js').StoreReferencesContainer['']} */ (entry).value.value;
// });
stores [ store _name ] = entry ;
}
if ( is _new || entry . store !== store ) {
entry . unsubscribe ( ) ;
entry . store = store ? ? null ;
entry . unsubscribe = connect _store _to _signal ( store , entry . value ) ;
}
const value = get ( entry . value ) ;
// This could happen if the store was cleaned up because the component was destroyed and there's a leak on the user side.
// In that case we don't want to fail with a cryptic Symbol error, but rather return the last value we got.
return value === UNINITIALIZED ? entry . last _value : value ;
}
/ * *
* @ template V
* @ param { import ( './types.js' ) . Store < V > | null | undefined } store
* @ param { import ( './types.js' ) . SourceSignal < V > } source
* /
function connect _store _to _signal ( store , source ) {
if ( store == null ) {
set ( source , undefined ) ;
return noop ;
}
/** @param {V} v */
const run = ( v ) => {
ignore _mutation _validation = true ;
set ( source , v ) ;
ignore _mutation _validation = false ;
} ;
return subscribe _to _store ( store , run ) ;
}
/ * *
* Sets the new value of a store and returns that value .
* @ template V
* @ param { import ( './types.js' ) . Store < V > } store
* @ param { V } value
* @ returns { V }
* /
export function store _set ( store , value ) {
store . set ( value ) ;
return value ;
}
/ * *
* Unsubscribes from all auto - subscribed stores on destroy
* @ param { import ( './types.js' ) . StoreReferencesContainer } stores
* /
export function unsubscribe _on _destroy ( stores ) {
on _destroy ( ( ) => {
let store _name ;
for ( store _name in stores ) {
const ref = stores [ store _name ] ;
ref . unsubscribe ( ) ;
// TODO: can we remove this code? it was refactored out when we split up source/comptued signals
// destroy_signal(ref.value);
}
} ) ;
}
/ * *
* @ template V
* @ param { import ( './types.js' ) . Signal < V > } signal
@ -1084,18 +818,6 @@ export function mutate(source, value) {
return value ;
}
/ * *
* Updates a store with a new value .
* @ param { import ( './types.js' ) . Store < V > } store the store to update
* @ param { any } expression the expression that mutates the store
* @ param { V } new _value the new store value
* @ template V
* /
export function mutate _store ( store , expression , new _value ) {
store . set ( new _value ) ;
return expression ;
}
/ * *
* @ param { import ( './types.js' ) . ComputationSignal } signal
* @ param { boolean } inert
@ -1295,67 +1017,6 @@ export function destroy_signal(signal) {
}
}
/ * *
* @ template V
* @ param { ( ) => V } init
* @ returns { import ( './types.js' ) . ComputationSignal < V > }
* /
/*#__NO_SIDE_EFFECTS__*/
export function derived ( init ) {
const is _unowned = current _effect === null ;
const flags = is _unowned ? DERIVED | UNOWNED : DERIVED ;
const signal = /** @type {import('./types.js').ComputationSignal<V>} */ (
create _computation _signal ( flags | CLEAN , UNINITIALIZED , current _block )
) ;
signal . i = init ;
signal . e = default _equals ;
if ( current _consumer !== null ) {
push _reference ( current _consumer , signal ) ;
}
return signal ;
}
/ * *
* @ template V
* @ param { ( ) => V } init
* @ returns { import ( './types.js' ) . ComputationSignal < V > }
* /
/*#__NO_SIDE_EFFECTS__*/
export function derived _safe _equal ( init ) {
const signal = derived ( init ) ;
signal . e = safe _equal ;
return signal ;
}
/ * *
* @ template V
* @ param { V } initial _value
* @ returns { import ( './types.js' ) . SourceSignal < V > }
* /
/*#__NO_SIDE_EFFECTS__*/
export function source ( initial _value ) {
return create _source _signal ( SOURCE | CLEAN , initial _value ) ;
}
/ * *
* @ template V
* @ param { V } initial _value
* @ returns { import ( './types.js' ) . SourceSignal < V > }
* /
/*#__NO_SIDE_EFFECTS__*/
export function mutable _source ( initial _value ) {
const s = source ( initial _value ) ;
s . e = safe _equal ;
// bind the signal to the component context, in case we need to
// track updates to trigger beforeUpdate/afterUpdate callbacks
if ( current _component _context ) {
( current _component _context . d ? ? = [ ] ) . push ( s ) ;
}
return s ;
}
/ * *
* Use ` untrack ` to prevent something from being treated as an ` $ effect ` / ` $ derived ` dependency .
*
@ -1374,170 +1035,6 @@ export function untrack(fn) {
}
}
/ * *
* @ param { import ( './types.js' ) . EffectType } type
* @ param { ( ( ) => void | ( ( ) => void ) ) | ( ( b : import ( './types.js' ) . Block ) => void | ( ( ) => void ) ) } init
* @ param { boolean } sync
* @ param { null | import ( './types.js' ) . Block } block
* @ param { boolean } schedule
* @ returns { import ( './types.js' ) . EffectSignal }
* /
function internal _create _effect ( type , init , sync , block , schedule ) {
const signal = create _computation _signal ( type | DIRTY , null , block ) ;
signal . i = init ;
signal . x = current _component _context ;
if ( current _effect !== null ) {
signal . l = current _effect . l + 1 ;
if ( ( type & MANAGED ) === 0 ) {
push _reference ( current _effect , signal ) ;
}
}
if ( schedule ) {
schedule _effect ( signal , sync ) ;
}
return signal ;
}
/ * *
* @ returns { boolean }
* /
export function effect _active ( ) {
return current _effect ? ( current _effect . f & MANAGED ) === 0 : false ;
}
/ * *
* @ param { ( ) => void | ( ( ) => void ) } init
* @ returns { import ( './types.js' ) . EffectSignal }
* /
export function user _effect ( init ) {
if ( current _effect === null ) {
throw new Error (
'ERR_SVELTE_ORPHAN_EFFECT' +
( DEV ? ': The Svelte $effect rune can only be used during component initialisation.' : '' )
) ;
}
const apply _component _effect _heuristics =
current _effect . f & RENDER _EFFECT &&
current _component _context !== null &&
! current _component _context . m ;
const effect = internal _create _effect (
EFFECT ,
init ,
false ,
current _block ,
! apply _component _effect _heuristics
) ;
if ( apply _component _effect _heuristics ) {
const context = /** @type {import('./types.js').ComponentContext} */ (
current _component _context
) ;
( context . e ? ? = [ ] ) . push ( effect ) ;
}
return effect ;
}
/ * *
* @ param { ( ) => void | ( ( ) => void ) } init
* @ returns { ( ) => void }
* /
export function user _root _effect ( init ) {
const effect = managed _render _effect ( init ) ;
return ( ) => {
destroy _signal ( effect ) ;
} ;
}
/ * *
* @ param { ( ) => void | ( ( ) => void ) } init
* @ returns { import ( './types.js' ) . EffectSignal }
* /
export function effect ( init ) {
return internal _create _effect ( EFFECT , init , false , current _block , true ) ;
}
/ * *
* @ param { ( ) => void | ( ( ) => void ) } init
* @ returns { import ( './types.js' ) . EffectSignal }
* /
export function managed _effect ( init ) {
return internal _create _effect ( EFFECT | MANAGED , init , false , current _block , true ) ;
}
/ * *
* @ param { ( ) => void | ( ( ) => void ) } init
* @ param { boolean } sync
* @ returns { import ( './types.js' ) . EffectSignal }
* /
export function managed _pre _effect ( init , sync ) {
return internal _create _effect ( PRE _EFFECT | MANAGED , init , sync , current _block , true ) ;
}
/ * *
* @ param { ( ) => void | ( ( ) => void ) } init
* @ returns { import ( './types.js' ) . EffectSignal }
* /
export function pre _effect ( init ) {
if ( current _effect === null ) {
throw new Error (
'ERR_SVELTE_ORPHAN_EFFECT' +
( DEV
? ': The Svelte $effect.pre rune can only be used during component initialisation.'
: '' )
) ;
}
const sync = current _effect !== null && ( current _effect . f & RENDER _EFFECT ) !== 0 ;
return internal _create _effect (
PRE _EFFECT ,
( ) => {
const val = init ( ) ;
flush _local _render _effects ( ) ;
return val ;
} ,
sync ,
current _block ,
true
) ;
}
/ * *
* This effect is used to ensure binding are kept in sync . We use a pre effect to ensure we run before the
* bindings which are in later effects . However , we don 't use a pre_effect directly as we don' t want to flush anything .
*
* @ param { ( ) => void | ( ( ) => void ) } init
* @ returns { import ( './types.js' ) . EffectSignal }
* /
export function invalidate _effect ( init ) {
return internal _create _effect ( PRE _EFFECT , init , true , current _block , true ) ;
}
/ * *
* @ template { import ( './types.js' ) . Block } B
* @ param { ( block : B ) => void | ( ( ) => void ) } init
* @ param { any } block
* @ param { any } managed
* @ param { any } sync
* @ returns { import ( './types.js' ) . EffectSignal }
* /
export function render _effect ( init , block = current _block , managed = false , sync = true ) {
let flags = RENDER _EFFECT ;
if ( managed ) {
flags |= MANAGED ;
}
return internal _create _effect ( flags , /** @type {any} */ ( init ) , sync , block , true ) ;
}
/ * *
* @ template { import ( './types.js' ) . Block } B
* @ param { ( block : B ) => void | ( ( ) => void ) } init
* @ param { any } block
* @ param { any } sync
* @ returns { import ( './types.js' ) . EffectSignal }
* /
export function managed _render _effect ( init , block = current _block , sync = true ) {
const flags = RENDER _EFFECT | MANAGED ;
return internal _create _effect ( flags , /** @type {any} */ ( init ) , sync , block , true ) ;
}
/ * *
* @ template V
* @ param { import ( './types.js' ) . ComputationSignal < V > } signal
@ -1562,7 +1059,7 @@ const STATUS_MASK = ~(DIRTY | MAYBE_DIRTY | CLEAN);
* @ param { number } status
* @ returns { void }
* /
export function set _signal _status ( signal , status ) {
function set _signal _status ( signal , status ) {
signal . f = ( signal . f & STATUS _MASK ) | status ;
}
@ -1579,154 +1076,6 @@ export function is_signal(val) {
) ;
}
/ * *
* @ template V
* @ param { unknown } val
* @ returns { val is import ( './types.js' ) . Store < V > }
* /
export function is _store ( val ) {
return (
typeof val === 'object' &&
val !== null &&
typeof ( /** @type {import('./types.js').Store<V>} */ ( val ) . subscribe ) === 'function'
) ;
}
/ * *
* This function is responsible for synchronizing a possibly bound prop with the inner component state .
* It is used whenever the compiler sees that the component writes to the prop , or when it has a default prop _value .
* @ template V
* @ param { Record < string , unknown > } props
* @ param { string } key
* @ param { number } flags
* @ param { V | ( ( ) => V ) } [ initial ]
* @ returns { ( ( ) => V | ( ( arg : V ) => V ) | ( ( arg : V , mutation : boolean ) => V ) ) }
* /
export function prop ( props , key , flags , initial ) {
var immutable = ( flags & PROPS _IS _IMMUTABLE ) !== 0 ;
var runes = ( flags & PROPS _IS _RUNES ) !== 0 ;
var prop _value = /** @type {V} */ ( props [ key ] ) ;
var setter = get _descriptor ( props , key ) ? . set ;
if ( prop _value === undefined && initial !== undefined ) {
if ( setter && runes ) {
// TODO consolidate all these random runtime errors
throw new Error (
'ERR_SVELTE_BINDING_FALLBACK' +
( DEV
? ` : Cannot pass undefined to bind: ${ key } because the property contains a fallback value. Pass a different value than undefined to ${ key } . `
: '' )
) ;
}
// @ts-expect-error would need a cumbersome method overload to type this
if ( ( flags & PROPS _IS _LAZY _INITIAL ) !== 0 ) initial = initial ( ) ;
prop _value = /** @type {V} */ ( initial ) ;
if ( setter ) setter ( prop _value ) ;
}
var getter = ( ) => {
var value = /** @type {V} */ ( props [ key ] ) ;
if ( value !== undefined ) initial = undefined ;
return value === undefined ? /** @type {V} */ ( initial ) : value ;
} ;
// easy mode — prop is never written to
if ( ( flags & PROPS _IS _UPDATED ) === 0 ) {
return getter ;
}
// intermediate mode — prop is written to, but the parent component had
// `bind:foo` which means we can just call `$$props.foo = value` directly
if ( setter ) {
return function ( /** @type {V} */ value ) {
if ( arguments . length === 1 ) {
/** @type {Function} */ ( setter ) ( value ) ;
return value ;
} else {
return getter ( ) ;
}
} ;
}
// hard mode. this is where it gets ugly — the value in the child should
// synchronize with the parent, but it should also be possible to temporarily
// set the value to something else locally.
var from _child = false ;
var was _from _child = false ;
// The derived returns the current value. The underlying mutable
// source is written to from various places to persist this value.
var inner _current _value = mutable _source ( prop _value ) ;
var current _value = derived ( ( ) => {
var parent _value = getter ( ) ;
var child _value = get ( inner _current _value ) ;
if ( from _child ) {
from _child = false ;
was _from _child = true ;
return child _value ;
}
was _from _child = false ;
return ( inner _current _value . v = parent _value ) ;
} ) ;
if ( ! immutable ) current _value . e = safe _equal ;
return function ( /** @type {V} */ value , mutation = false ) {
var current = get ( current _value ) ;
// legacy nonsense — need to ensure the source is invalidated when necessary
// also needed for when handling inspect logic so we can inspect the correct source signal
if ( is _signals _recorded || ( DEV && inspect _fn ) ) {
// set this so that we don't reset to the parent value if `d`
// is invalidated because of `invalidate_inner_signals` (rather
// than because the parent or child value changed)
from _child = was _from _child ;
// invoke getters so that signals are picked up by `invalidate_inner_signals`
getter ( ) ;
get ( inner _current _value ) ;
}
if ( arguments . length > 0 ) {
if ( mutation || ( immutable ? value !== current : safe _not _equal ( value , current ) ) ) {
from _child = true ;
set ( inner _current _value , mutation ? current : value ) ;
get ( current _value ) ; // force a synchronisation immediately
}
return value ;
}
return current ;
} ;
}
/ * *
* @ param { unknown } a
* @ param { unknown } b
* @ returns { boolean }
* /
export function safe _not _equal ( a , b ) {
// eslint-disable-next-line eqeqeq
return a != a
? // eslint-disable-next-line eqeqeq
b == b
: a !== b || ( a !== null && typeof a === 'object' ) || typeof a === 'function' ;
}
/ * *
* @ param { unknown } a
* @ param { unknown } b
* @ returns { boolean }
* /
export function safe _equal ( a , b ) {
return ! safe _not _equal ( a , b ) ;
}
/** @returns {Map<unknown, unknown>} */
export function get _or _init _context _map ( ) {
const component _context = current _component _context ;
@ -1755,23 +1104,6 @@ function get_parent_context(component_context) {
return null ;
}
/ * *
* @ this { any }
* @ param { Record < string , unknown > } $$props
* @ param { Event } event
* @ returns { void }
* /
export function bubble _event ( $$props , event ) {
var events = /** @type {Record<string, Function[] | Function>} */ ( $$props . $$events ) ? . [
event . type
] ;
var callbacks = is _array ( events ) ? events . slice ( ) : events == null ? [ ] : [ events ] ;
for ( var fn of callbacks ) {
// Preserve "this" context
fn . call ( this , event ) ;
}
}
/ * *
* @ param { import ( './types.js' ) . Signal < number > } signal
* @ param { 1 | - 1 } [ d ]
@ -1794,17 +1126,6 @@ export function update_prop(fn, d = 1) {
return value ;
}
/ * *
* @ param { import ( './types.js' ) . Store < number > } store
* @ param { number } store _value
* @ param { 1 | - 1 } [ d ]
* @ returns { number }
* /
export function update _store ( store , store _value , d = 1 ) {
store . set ( store _value + d ) ;
return store _value ;
}
/ * *
* @ param { import ( './types.js' ) . Signal < number > } signal
* @ param { 1 | - 1 } [ d ]
@ -1827,36 +1148,6 @@ export function update_pre_prop(fn, d = 1) {
return value ;
}
/ * *
* @ param { import ( './types.js' ) . Store < number > } store
* @ param { number } store _value
* @ param { 1 | - 1 } [ d ]
* @ returns { number }
* /
export function update _pre _store ( store , store _value , d = 1 ) {
const value = store _value + d ;
store . set ( value ) ;
return value ;
}
/ * *
* Under some circumstances , imports may be reactive in legacy mode . In that case ,
* they should be using ` reactive_import ` as part of the transformation
* @ param { ( ) => any } fn
* /
export function reactive _import ( fn ) {
const s = source ( 0 ) ;
return function ( ) {
if ( arguments . length === 1 ) {
set ( s , get ( s ) + 1 ) ;
return arguments [ 0 ] ;
} else {
get ( s ) ;
return fn ( ) ;
}
} ;
}
/ * *
* @ param { Record < string , unknown > } obj
* @ param { string [ ] } keys
@ -1881,15 +1172,6 @@ export function value_or_fallback(value, fallback) {
return value === undefined ? fallback : value ;
}
/ * *
* Schedules a callback to run immediately before the component is unmounted .
* @ param { ( ) => any } fn
* @ returns { void }
* /
function on _destroy ( fn ) {
user _effect ( ( ) => ( ) => untrack ( fn ) ) ;
}
/ * *
* @ param { Record < string , unknown > } props
* @ param { any } runes
@ -1951,53 +1233,6 @@ export function pop(component) {
return component || /** @type {T} */ ( { } ) ;
}
/ * *
* Invoke the getter of all signals associated with a component
* so they can be registered to the effect this function is called in .
* @ param { import ( './types.js' ) . ComponentContext } context
* /
function observe _all ( context ) {
if ( context . d ) {
for ( const signal of context . d ) get ( signal ) ;
}
deep _read ( context . s ) ;
}
/ * *
* Legacy - mode only : Call ` onMount ` callbacks and set up ` beforeUpdate ` / ` afterUpdate ` effects
* /
export function init ( ) {
const context = /** @type {import('./types.js').ComponentContext} */ ( current _component _context ) ;
const callbacks = context . u ;
if ( ! callbacks ) return ;
// beforeUpdate
pre _effect ( ( ) => {
observe _all ( context ) ;
callbacks . b . forEach ( run ) ;
} ) ;
// onMount (must run before afterUpdate)
user _effect ( ( ) => {
const fns = untrack ( ( ) => callbacks . m . map ( run ) ) ;
return ( ) => {
for ( const fn of fns ) {
if ( typeof fn === 'function' ) {
fn ( ) ;
}
}
} ;
} ) ;
// afterUpdate
user _effect ( ( ) => {
observe _all ( context ) ;
callbacks . a . forEach ( run ) ;
} ) ;
}
/ * *
* Deeply traverse an object and read all its properties
* so that they ' re all reactive in case this is ` $ state `