2023-12-24 09:14:46 -06:00
function deep _copy ( from ) { return json . decode ( json . encode ( from ) ) ; }
2023-04-22 16:44:26 -05:00
var walk _up _get _prop = function ( obj , prop , endobj ) {
var props = [ ] ;
var cur = obj ;
while ( cur !== Object . prototype ) {
if ( cur . hasOwn ( prop ) )
props . push ( cur [ prop ] ) ;
cur = cur . _ _proto _ _ ;
}
return props ;
} ;
/* Deeply remove source keys from target, not removing objects */
function unmerge ( target , source ) {
for ( var key in source ) {
if ( typeof source [ key ] === 'object' && ! Array . isArray ( source [ key ] ) )
unmerge ( target [ key ] , source [ key ] ) ;
else
delete target [ key ] ;
}
} ;
/* Deeply merge two objects, not clobbering objects on target with objects on source */
function deep _merge ( target , source )
{
2023-04-28 12:49:18 -05:00
Log . warn ( "Doing a deep merge ..." ) ;
2023-04-22 16:44:26 -05:00
for ( var key in source ) {
2023-04-28 12:49:18 -05:00
if ( typeof source [ key ] === 'object' && ! Array . isArray ( source [ key ] ) ) {
2023-04-29 10:07:58 -05:00
Log . warn ( ` Deeper merge on ${ key } ` ) ;
2023-04-22 16:44:26 -05:00
deep _merge ( target [ key ] , source [ key ] ) ;
2023-04-28 12:49:18 -05:00
}
else {
2023-04-29 10:07:58 -05:00
Log . warn ( ` Setting key ${ key } ` ) ;
2023-04-22 16:44:26 -05:00
target [ key ] = source [ key ] ;
2023-04-28 12:49:18 -05:00
}
2023-04-22 16:44:26 -05:00
}
} ;
function equal ( x , y ) {
if ( typeof x === 'object' )
2023-12-24 09:14:46 -06:00
return json . encode ( x ) === json . encode ( y ) ;
2023-04-22 16:44:26 -05:00
return x === y ;
} ;
function diffassign ( target , from ) {
if ( from . empty ) return ;
for ( var e in from ) {
if ( typeof from [ e ] === 'object' ) {
if ( ! target . hasOwnProperty ( e ) )
target [ e ] = from [ e ] ;
else
diffassign ( target [ e ] , from [ e ] ) ;
} else {
if ( from [ e ] === "DELETE" ) {
delete target [ e ] ;
} else {
target [ e ] = from [ e ] ;
}
}
}
} ;
2023-10-26 11:48:02 -05:00
function objdiff ( from , to )
2023-10-02 17:03:01 -05:00
{
2023-10-05 17:30:17 -05:00
var ret = { } ;
2023-10-09 18:10:10 -05:00
if ( ! to )
return ediff ( from , { } ) ;
2023-10-05 17:30:17 -05:00
Object . entries ( from ) . forEach ( function ( [ key , v ] ) {
if ( typeof v === 'function' ) return ;
if ( typeof v === 'undefined' ) return ;
2023-10-05 08:02:12 -05:00
2023-10-05 17:30:17 -05:00
if ( Array . isArray ( v ) ) {
if ( ! Array . isArray ( to [ key ] ) || v . length !== to [ key ] . length )
ret [ key ] = Object . values ( ediff ( v , [ ] ) ) ;
2023-10-05 08:02:12 -05:00
2023-10-05 17:30:17 -05:00
var diff = ediff ( from [ key ] , to [ key ] ) ;
if ( diff && ! diff . empty )
ret [ key ] = Object . values ( ediff ( v , [ ] ) ) ;
2023-10-05 08:02:12 -05:00
2023-10-05 17:30:17 -05:00
return ;
2023-10-05 08:02:12 -05:00
}
2023-10-05 17:30:17 -05:00
if ( typeof v === 'object' ) {
var diff = ediff ( v , to [ key ] ) ;
if ( diff && ! diff . empty )
ret [ key ] = diff ;
return ;
}
2023-04-22 16:44:26 -05:00
2023-10-05 17:30:17 -05:00
if ( typeof v === 'number' ) {
2023-12-24 09:14:46 -06:00
if ( ! to || v !== to [ key ] )
ret [ key ] = v ;
2023-10-05 17:30:17 -05:00
return ;
2023-04-22 16:44:26 -05:00
}
2023-10-05 17:30:17 -05:00
if ( ! to || v !== to [ key ] )
ret [ key ] = v ;
} ) ;
2023-10-10 17:37:58 -05:00
if ( ret . empty ) return undefined ;
2023-10-05 17:30:17 -05:00
return ret ;
}
2023-10-26 11:48:02 -05:00
function valdiff ( from , to )
{
if ( typeof from !== typeof to ) return from ;
if ( typeof from === 'function' ) return undefined ;
if ( typeof from === 'undefined' ) return undefined ;
if ( typeof from === 'number' ) {
return to ;
return undefined ;
}
if ( typeof from === 'object' )
return ediff ( from , to ) ;
if ( from !== to ) return to ;
return undefined ;
}
2023-12-24 09:14:46 -06:00
/* Returns the json encoded object, assuming it has an implementation it must check through */
function impl _json ( obj )
{
}
2023-10-26 11:48:02 -05:00
2023-12-24 09:14:46 -06:00
function ndiff ( from , to )
{
}
2023-10-26 11:48:02 -05:00
function ediff ( from , to )
{
var ret = { } ;
if ( ! to )
// return ediff(from, {});
return deep _copy ( from ) ;
Object . entries ( from ) . forEach ( function ( [ key , v ] ) {
if ( typeof v === 'function' ) return ;
if ( typeof v === 'undefined' ) return ;
if ( Array . isArray ( v ) ) {
2023-11-06 07:05:27 -06:00
if ( ! Array . isArray ( to [ key ] ) || v . length !== to [ key ] . length ) {
var r = ediff ( v , [ ] ) ;
if ( r ) ret [ key ] = Object . values ( r ) ;
return ;
}
2023-10-26 11:48:02 -05:00
var diff = ediff ( from [ key ] , to [ key ] ) ;
if ( diff && ! diff . empty )
ret [ key ] = Object . values ( ediff ( v , [ ] ) ) ;
return ;
}
if ( typeof v === 'object' ) {
var diff = ediff ( v , to [ key ] ) ;
if ( diff && ! diff . empty )
ret [ key ] = diff ;
return ;
}
if ( typeof v === 'number' ) {
2023-12-24 09:14:46 -06:00
if ( ! to || v !== to [ key ] )
ret [ key ] = v ;
2023-10-26 11:48:02 -05:00
return ;
}
if ( ! to || v !== to [ key ] )
ret [ key ] = v ;
} ) ;
if ( ret . empty ) return undefined ;
return ret ;
}
ediff . doc = "Given a from and to object, returns an object that, if applied to from, will make it the same as to. Does not include deletion; it is only additive." ;
function subdiff ( from , to )
{
}
subdiff . doc = "Given a from and to object, returns a list of properties that must be deleted from the 'from' object to make it like the 'to' object." ;
function samediff ( from , to )
{
var same = [ ] ;
if ( ! to ) return same ;
if ( typeof to !== 'object' ) {
Log . warn ( "'To' must be an object. Got " + to ) ;
return same ;
}
Object . keys ( from ) . forEach ( function ( k ) {
if ( Object . isObject ( from [ k ] ) ) {
samediff ( from [ k ] , to [ k ] ) ;
return ;
}
// if (Array.isArray(from[k])) {
// var d = valdiff(from[k], to[k]);
// if (!d)
// }
var d = valdiff ( from [ k ] , to [ k ] ) ;
if ( ! d )
delete from [ k ] ;
} ) ;
return same ;
}
samediff . doc = "Given a from and to object, returns an array of keys that are the same on from as on to." ;
function cleandiff ( from , to )
{
}