File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11import { Signal , createSignal , onCleanup } from "solid-js" ;
22import type { LocationChange , RouterContext , RouterUtils } from "../types.ts" ;
33import { createRouterComponent } from "./components.jsx" ;
4+ import { equalObjects } from "../utils.js" ;
45
56function intercept < T > (
67 [ value , setValue ] : [ ( ) => T , ( v : T ) => void ] ,
@@ -32,7 +33,9 @@ export function createRouter(config: {
3233 let ignore = false ;
3334 const wrap = ( value : string | LocationChange ) => ( typeof value === "string" ? { value } : value ) ;
3435 const signal = intercept < LocationChange > (
35- createSignal ( wrap ( config . get ( ) ) , { equals : false } ) ,
36+ createSignal ( wrap ( config . get ( ) ) , {
37+ equals : ( a , b ) => a . value === b . value && equalObjects ( a . state , b . state )
38+ } ) ,
3639 undefined ,
3740 next => {
3841 ! ignore && config . set ( next ) ;
Original file line number Diff line number Diff line change @@ -44,7 +44,8 @@ import {
4444 joinPaths ,
4545 scoreRoute ,
4646 mergeSearchString ,
47- expandOptionals
47+ expandOptionals ,
48+ equalObjects
4849} from "./utils.js" ;
4950
5051const MAX_REDIRECTS = 100 ;
@@ -327,26 +328,19 @@ export function createRouterContext(
327328 } ;
328329
329330 createRenderEffect ( ( ) => {
330- const { value, state } = source ( ) ;
331+ const { value, state : nextState } = source ( ) ;
331332 // Untrack this whole block so `start` doesn't cause Solid's Listener to be preserved
332333 untrack ( ( ) => {
333- if ( value !== reference ( ) ) {
334+ if ( value !== reference ( ) || ! equalObjects ( nextState , state ( ) ) ) {
334335 start ( ( ) => {
335336 intent = "native" ;
336337 setReference ( value ) ;
337- setState ( state ) ;
338+ setState ( nextState ) ;
338339 resetErrorBoundaries ( ) ;
339340 submissions [ 1 ] ( [ ] ) ;
340341 } ) . then ( ( ) => {
341342 intent = undefined ;
342343 } ) ;
343- } else {
344- start ( ( ) => {
345- intent = "native" ;
346- setState ( state ) ;
347- } ) . then ( ( ) => {
348- intent = undefined ;
349- } ) ;
350344 }
351345 } ) ;
352346 } ) ;
Original file line number Diff line number Diff line change @@ -186,3 +186,34 @@ export function expandOptionals(pattern: string): string[] {
186186 [ ]
187187 ) ;
188188}
189+
190+ // Modified from fast-deep-equal for objects only (MIT)
191+ // https://github.com/epoberezkin/fast-deep-equal
192+ export function equalObjects ( a : any , b : any ) {
193+ if ( a === b ) return true ;
194+
195+ if ( a && b && typeof a == "object" && typeof b == "object" ) {
196+ if ( a . constructor !== b . constructor ) return false ;
197+ if ( a . valueOf !== Object . prototype . valueOf ) return a . valueOf ( ) === b . valueOf ( ) ;
198+ if ( a . toString !== Object . prototype . toString ) return a . toString ( ) === b . toString ( ) ;
199+
200+ var length , i , keys ;
201+ keys = Object . keys ( a ) ;
202+ length = keys . length ;
203+
204+ if ( length !== Object . keys ( b ) . length ) return false ;
205+
206+ for ( i = length ; i -- !== 0 ; ) {
207+ if ( ! Object . prototype . hasOwnProperty . call ( b , keys [ i ] ) ) return false ;
208+ }
209+
210+ for ( i = length ; i -- !== 0 ; ) {
211+ var key = keys [ i ] ;
212+ if ( ! equalObjects ( a [ key ] , b [ key ] ) ) return false ;
213+ }
214+
215+ return true ;
216+ }
217+
218+ return false ;
219+ }
You can’t perform that action at this time.
0 commit comments