@@ -64,7 +64,7 @@ let current_dependencies = null;
6464let current_dependencies_index = 0 ;
6565/** @type {null | import('./types.js').Signal[] } */
6666let current_untracked_writes = null ;
67- /** @type {null | import('./types.js').Signal } */
67+ /** @type {null | import('./types.js').SignalDebug } */
6868let last_inspected_signal = null ;
6969/** If `true`, `get`ting the signal should not register it as a dependency */
7070export let current_untracking = false ;
@@ -81,7 +81,7 @@ let captured_signals = new Set();
8181/** @type {Function | null } */
8282let inspect_fn = null ;
8383
84- /** @type {Array<import('./types.js').SourceSignal & import('./types.js').SourceSignalDebug > } */
84+ /** @type {Array<import('./types.js').SignalDebug > } */
8585let inspect_captured_signals = [ ] ;
8686
8787// Handle rendering tree blocks and anchors
@@ -127,7 +127,6 @@ export function batch_inspect(target, prop, receiver) {
127127 } finally {
128128 is_batching_effect = previously_batching_effect ;
129129 if ( last_inspected_signal !== null ) {
130- // @ts -expect-error
131130 for ( const fn of last_inspected_signal . inspect ) fn ( ) ;
132131 last_inspected_signal = null ;
133132 }
@@ -737,8 +736,7 @@ function update_derived(signal, force_schedule) {
737736
738737 // @ts -expect-error
739738 if ( DEV && signal . inspect && force_schedule ) {
740- // @ts -expect-error
741- for ( const fn of signal . inspect ) fn ( ) ;
739+ for ( const fn of /** @type {import('./types.js').SignalDebug } */ ( signal ) . inspect ) fn ( ) ;
742740 }
743741 }
744742}
@@ -841,8 +839,7 @@ export function unsubscribe_on_destroy(stores) {
841839export function get ( signal ) {
842840 // @ts -expect-error
843841 if ( DEV && signal . inspect && inspect_fn ) {
844- // @ts -expect-error
845- signal . inspect . add ( inspect_fn ) ;
842+ /** @type {import('./types.js').SignalDebug } */ ( signal ) . inspect . add ( inspect_fn ) ;
846843 // @ts -expect-error
847844 inspect_captured_signals . push ( signal ) ;
848845 }
@@ -1111,10 +1108,9 @@ export function set_signal_value(signal, value) {
11111108 // @ts -expect-error
11121109 if ( DEV && signal . inspect ) {
11131110 if ( is_batching_effect ) {
1114- last_inspected_signal = signal ;
1111+ last_inspected_signal = /** @type { import('./types.js').SignalDebug } */ ( signal ) ;
11151112 } else {
1116- // @ts -expect-error
1117- for ( const fn of signal . inspect ) fn ( ) ;
1113+ for ( const fn of /** @type {import('./types.js').SignalDebug } */ ( signal ) . inspect ) fn ( ) ;
11181114 }
11191115 }
11201116 }
@@ -1836,6 +1832,37 @@ function deep_read(value, visited = new Set()) {
18361832 }
18371833}
18381834
1835+ /**
1836+ * Like `unstate`, but recursively traverses into normal arrays/objects to find potential states in them.
1837+ * @param {any } value
1838+ * @param {Map<any, any> } visited
1839+ * @returns {any }
1840+ */
1841+ function deep_unstate ( value , visited = new Map ( ) ) {
1842+ if ( typeof value === 'object' && value !== null && ! visited . has ( value ) ) {
1843+ const unstated = unstate ( value ) ;
1844+ if ( unstated !== value ) {
1845+ visited . set ( value , unstated ) ;
1846+ return unstated ;
1847+ }
1848+
1849+ let contains_unstated = false ;
1850+ /** @type {any } */
1851+ const nested_unstated = Array . isArray ( value ) ? [ ] : { } ;
1852+ for ( let key in value ) {
1853+ const result = deep_unstate ( value [ key ] , visited ) ;
1854+ nested_unstated [ key ] = result ;
1855+ if ( result !== value [ key ] ) {
1856+ contains_unstated = true ;
1857+ }
1858+ }
1859+
1860+ visited . set ( value , contains_unstated ? nested_unstated : value ) ;
1861+ }
1862+
1863+ return visited . get ( value ) ?? value ;
1864+ }
1865+
18391866// TODO remove in a few versions, before 5.0 at the latest
18401867let warned_inspect_changed = false ;
18411868
@@ -1849,7 +1876,7 @@ export function inspect(get_value, inspect = console.log) {
18491876
18501877 pre_effect ( ( ) => {
18511878 const fn = ( ) => {
1852- const value = get_value ( ) . map ( unstate ) ;
1879+ const value = get_value ( ) . map ( ( v ) => deep_unstate ( v ) ) ;
18531880 if ( value . length === 2 && typeof value [ 1 ] === 'function' && ! warned_inspect_changed ) {
18541881 // eslint-disable-next-line no-console
18551882 console . warn (
0 commit comments