@@ -21,7 +21,7 @@ const captureState = cmp => {
2121 }
2222
2323 const {
24- $$ : { callbacks, bound, ctx, props, hmr_future_props } ,
24+ $$ : { callbacks, bound, ctx, props } ,
2525 } = cmp
2626
2727 const state = cmp . $capture_state ( )
@@ -37,14 +37,51 @@ const captureState = cmp => {
3737 return {
3838 ctx,
3939 props,
40- hmr_future_props,
4140 callbacks,
4241 bound,
4342 state,
4443 hmr_props_values,
4544 }
4645}
4746
47+ // remapping all existing bindings (including hmr_future_foo ones) to the
48+ // new version's props indexes, and refresh them with the new value from
49+ // context
50+ const restoreBound = ( cmp , restore ) => {
51+ // reverse prop:ctxIndex in $$.props to ctxIndex:prop
52+ //
53+ // ctxIndex can be either a regular index in $$.ctx or a hmr_future_ prop
54+ //
55+ const propsByIndex = { }
56+ for ( const [ name , i ] of Object . entries ( restore . props ) ) {
57+ propsByIndex [ i ] = name
58+ }
59+
60+ // NOTE $$.bound cannot change in the HMR lifetime of a component, because
61+ // if bindings changes, that means the parent component has changed,
62+ // which means the child (current) component will be wholly recreated
63+ for ( const [ oldIndex , updateBinding ] of Object . entries ( restore . bound ) ) {
64+ // can be either regular prop, or future_hmr_ prop
65+ const propName = propsByIndex [ oldIndex ]
66+
67+ // this should never happen if remembering of future props is enabled...
68+ // in any case, there's nothing we can do about it if we have lost prop
69+ // name knowledge at this point
70+ if ( propName == null ) continue
71+
72+ // NOTE $$.props[propName] also propagates knowledge of a possible
73+ // future prop to the new $$.props (via $$.props being a Proxy)
74+ const newIndex = cmp . $$ . props [ propName ]
75+ cmp . $$ . bound [ newIndex ] = updateBinding
76+
77+ // NOTE if the prop doesn't exist or doesn't exist anymore in the new
78+ // version of the component, clearing the binding is the expected
79+ // behaviour (since that's what would happen in non HMR code)
80+ const newValue = cmp . $$ . ctx [ newIndex ]
81+ updateBinding ( newValue )
82+ }
83+ }
84+
4885// restoreState
4986//
5087// It is too late to restore context at this point because component instance
@@ -54,32 +91,16 @@ const captureState = cmp => {
5491// also generally more respectful of normal operation.
5592//
5693const restoreState = ( cmp , restore ) => {
57- if ( ! restore ) {
58- return
59- }
60- const { callbacks, bound, hmr_future_props } = restore
94+ if ( ! restore ) return
6195
62- if ( callbacks ) {
63- cmp . $$ . callbacks = callbacks
96+ if ( restore . callbacks ) {
97+ cmp . $$ . callbacks = restore . callbacks
6498 }
6599
66- if ( bound ) {
67- const propsByIndex = { }
68- for ( const [ name , i ] of Object . entries ( restore . props ) ) {
69- propsByIndex [ i ] = name
70- }
71- for ( const oldIndex of Object . keys ( bound ) ) {
72- const callback = bound [ oldIndex ]
73- const propName = hmr_future_props [ - oldIndex - 1 ] || propsByIndex [ oldIndex ]
74- if ( propName == null ) continue
75- const newIndex = cmp . $$ . props [ propName ]
76- cmp . $$ . bound [ newIndex ] = callback
77- // NOTE if the prop doesn't exist or doesn't exist anymore in the new
78- // version of the component, clearing the binding is the expected
79- // behaviour (since that's what would happen in non HMR code)
80- callback ( cmp . $$ . ctx [ newIndex ] )
81- }
100+ if ( restore . bound ) {
101+ restoreBound ( cmp , restore )
82102 }
103+
83104 // props, props.$$slots are restored at component creation (works
84105 // better -- well, at all actually)
85106}
@@ -164,15 +185,12 @@ export const createProxiedComponent = (
164185 // https://github.com/sveltejs/svelte/blob/1632bca34e4803d6b0e0b0abd652ab5968181860/src/runtime/internal/Component.ts#L46
165186 //
166187 const rememberFutureProps = cmp => {
167- cmp . $$ . hmr_future_props = [ ]
168-
169188 if ( typeof Proxy === 'undefined' ) return
170189
171190 cmp . $$ . props = new Proxy ( cmp . $$ . props , {
172191 get ( target , name ) {
173192 if ( target [ name ] === undefined ) {
174- cmp . $$ . hmr_future_props . push ( name )
175- return - cmp . $$ . hmr_future_props . length
193+ target [ name ] = 'hmr_future_' + name
176194 }
177195 return target [ name ]
178196 } ,
0 commit comments