-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgs-utils-data.js
More file actions
92 lines (82 loc) · 2.49 KB
/
Copy pathgs-utils-data.js
File metadata and controls
92 lines (82 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
"use strict";
class GSData {
#data = null;
#listeners = [];
constructor( obj = {} ) {
this.#data = GSUdeepFreeze( GSUdeepCopy( obj ) );
}
// .........................................................................
$getData( path = "" ) {
return GSUdotProp( this.#data, path );
}
// .........................................................................
$removeListeners( elem ) {
GSUarrayRemove( this.#listeners, l => l[ 0 ] === elem );
}
$addListeners( elem, cbs ) {
this.#listeners.push( [ elem, cbs.map( ( [ path, fn ] ) => {
const target = GSUdotProp( this.#data, path );
const fn2 = fn.bind( elem );
if ( target !== undefined ) {
const calls = [];
if ( !GSUisObj( target ) ) {
calls.push( [ "create", target ] );
} else {
GSUforEach( target, ( v, k ) => calls.push( [ "create", k, v ] ) );
}
if ( calls.length > 0 ) {
fn2( calls );
}
}
return [ path, fn2 ];
} ) ] );
}
// .........................................................................
$assign( obj ) {
const oldData = GSUdeepCopy( this.#data );
const newData = GSUdeepFreeze( GSUdiffAssign( GSUdeepCopy( oldData ), obj ) );
const dataDiff = GSUdiffObjects( oldData, newData );
if ( dataDiff ) {
this.#data = newData;
this.#listeners.forEach( GSData.#assign.bind( null, oldData, newData, dataDiff ) );
}
}
static #assign( oldData, data, dataDiff, [ _elem, cbs ] ) {
cbs.forEach( ( [ path, fn ] ) => {
const targetDiff = GSUdotProp( dataDiff, path );
if ( targetDiff !== undefined ) {
const calls = [];
const targetData = GSUdotProp( oldData, path );
GSData.#assign2( calls, targetDiff, targetData, data, path );
if ( calls.length > 0 ) {
fn( calls );
}
}
} );
}
static #assign2( calls, targetDiff, targetData, newData, path ) {
if ( targetDiff === GSUdotProp.$undefined ) {
if ( targetData !== undefined ) {
calls.push( [ "delete" ] );
}
} else if ( targetData === undefined ) {
calls.push( [ "create", targetDiff ] );
} else if ( !GSUisObj( targetDiff ) ) {
calls.push( [ "update", targetDiff ] );
} else {
GSUforEach( targetDiff, ( v, k ) => {
if ( v === undefined ) {
if ( targetData[ k ] ) {
calls.push( [ "delete", k ] );
}
} else if ( targetDiff[ k ] !== targetData[ k ] ) {
if ( targetData[ k ] === undefined ) {
calls.push( [ "create", k, v, v ] );
} else {
calls.push( [ "update", k, v, GSUdotProp( newData, path )[ k ] ] );
}
}
} );
}
}
}