11import { CachedMetadata , TFile } from 'obsidian' ;
22import MetaBindPlugin from './main' ;
33import { setFrontmatterOfTFile } from '@opd-libs/opd-metadata-lib/lib/API' ;
4- import { traverseObjectToParent } from '@opd-libs/opd-metadata-lib/lib/Utils' ;
4+ import { traverseObjectByPath } from '@opd-libs/opd-metadata-lib/lib/Utils' ;
55import { Internal } from '@opd-libs/opd-metadata-lib/lib/Internal' ;
6+ import { arrayEquals , traverseObjectToParentByPath } from './utils/Utils' ;
67import getMetaDataFromFileContent = Internal . getMetaDataFromFileContent ;
78
89export interface MetadataFileCache {
910 file : TFile ;
1011 metadata : Record < string , any > ;
1112 listeners : {
12- onCacheUpdate : ( metadata : Record < string , any > ) => void ;
13+ onCacheUpdate : ( value : any | undefined ) => void ;
14+ metadataPath : string [ ] ;
1315 uuid : string ;
1416 } [ ] ;
1517 cyclesSinceLastUpdate : number ;
@@ -32,24 +34,25 @@ export class MetadataManager {
3234 this . interval = window . setInterval ( ( ) => this . update ( ) , this . plugin . settings . syncInterval ) ;
3335 }
3436
35- register ( file : TFile , onCacheUpdate : ( metadata : Record < string , any > ) => void , uuid : string ) : MetadataFileCache {
37+ register ( file : TFile , onCacheUpdate : ( value : any ) => void , metadataPath : string [ ] , uuid : string ) : MetadataFileCache {
3638 const fileCache = this . getCacheForFile ( file ) ;
3739 if ( fileCache ) {
38- console . debug ( `meta-bind | MetadataManager >> registered ${ uuid } to existing file cache ${ file . path } ` ) ;
39- fileCache . listeners . push ( { onCacheUpdate, uuid } ) ;
40+ console . debug ( `meta-bind | MetadataManager >> registered ${ uuid } to existing file cache ${ file . path } -> ${ metadataPath } ` ) ;
41+ fileCache . listeners . push ( { onCacheUpdate, metadataPath , uuid } ) ;
4042 return fileCache ;
4143 } else {
42- console . debug ( `meta-bind | MetadataManager >> registered ${ uuid } to newly created file cache ${ file . path } ` ) ;
44+ console . debug ( `meta-bind | MetadataManager >> registered ${ uuid } to newly created file cache ${ file . path } -> ${ metadataPath } ` ) ;
4345 const c : MetadataFileCache = {
4446 file : file ,
4547 metadata : { } ,
46- listeners : [ { onCacheUpdate, uuid } ] ,
48+ listeners : [ { onCacheUpdate, metadataPath , uuid } ] ,
4749 cyclesSinceLastUpdate : 0 ,
4850 changed : false ,
4951 } ;
5052
5153 this . plugin . app . vault . cachedRead ( file ) . then ( value => {
5254 c . metadata = getMetaDataFromFileContent ( value ) ;
55+ console . log ( `meta-bind | MetadataManager >> loaded metadata for file ${ file . path } ` , c . metadata ) ;
5356 this . notifyListeners ( c ) ;
5457 } ) ;
5558
@@ -106,28 +109,34 @@ export class MetadataManager {
106109 fileCache . metadata = metadata ;
107110 fileCache . cyclesSinceLastUpdate = 0 ;
108111
109- this . notifyListeners ( fileCache , uuid ) ;
112+ this . notifyListeners ( fileCache , undefined , uuid ) ;
110113 }
111114
112- updatePropertyInMetadataFileCache ( value : any , path : string , file : TFile , uuid ?: string | undefined ) : void {
113- console . debug ( `meta-bind | MetadataManager >> updating ${ path } in ${ file . path } metadata cache to` , value ) ;
115+ updatePropertyInMetadataFileCache ( value : any , pathParts : string [ ] , file : TFile , uuid ?: string | undefined ) : void {
116+ console . debug ( `meta-bind | MetadataManager >> updating ${ pathParts } in ${ file . path } metadata cache to` , value ) ;
117+ console . trace ( ) ;
114118
115119 const fileCache = this . getCacheForFile ( file ) ;
116120 if ( ! fileCache ) {
117121 return ;
118122 }
119123
120- const { parent, child } = traverseObjectToParent ( path , fileCache . metadata ) ;
124+ const { parent, child } = traverseObjectToParentByPath ( pathParts , fileCache . metadata ) ;
121125
122126 if ( parent . value === undefined ) {
123- throw Error ( `The parent of "${ path } " does not exist in Object, please create the parent first` ) ;
127+ throw Error ( `The parent of "${ pathParts } " does not exist in Object, please create the parent first` ) ;
128+ }
129+
130+ if ( child . value === value ) {
131+ console . debug ( `meta-bind | MetadataManager >> skipping redundant update of ${ pathParts } in ${ file . path } metadata cache` , value ) ;
132+ return ;
124133 }
125134
126135 parent . value [ child . key ] = value ;
127136 fileCache . cyclesSinceLastUpdate = 0 ;
128137 fileCache . changed = true ;
129138
130- this . notifyListeners ( fileCache , uuid ) ;
139+ this . notifyListeners ( fileCache , pathParts , uuid ) ;
131140 }
132141
133142 updateMetadataFileCacheOnFrontmatterUpdate ( file : TFile , data : string , cache : CachedMetadata ) : void {
@@ -152,13 +161,26 @@ export class MetadataManager {
152161 this . notifyListeners ( fileCache ) ;
153162 }
154163
155- notifyListeners ( fileCache : MetadataFileCache , exceptUuid ?: string | undefined ) : void {
164+ notifyListeners ( fileCache : MetadataFileCache , metadataPath ?: string [ ] | undefined , exceptUuid ?: string | undefined ) : void {
165+ let value ;
166+ if ( metadataPath ) {
167+ value = traverseObjectByPath ( metadataPath , fileCache . metadata ) ;
168+ }
169+
156170 for ( const listener of fileCache . listeners ) {
157171 if ( exceptUuid && exceptUuid === listener . uuid ) {
158172 continue ;
159173 }
160- console . debug ( `meta-bind | MetadataManager >> notifying input field ${ listener . uuid } of updated metadata` ) ;
161- listener . onCacheUpdate ( fileCache . metadata ) ;
174+
175+ if ( metadataPath ) {
176+ if ( arrayEquals ( metadataPath , listener . metadataPath ) ) {
177+ console . debug ( `meta-bind | MetadataManager >> notifying input field ${ listener . uuid } of updated metadata` ) ;
178+ listener . onCacheUpdate ( value ) ;
179+ }
180+ } else {
181+ console . debug ( `meta-bind | MetadataManager >> notifying input field ${ listener . uuid } of updated metadata` ) ;
182+ listener . onCacheUpdate ( traverseObjectByPath ( listener . metadataPath , fileCache . metadata ) ) ;
183+ }
162184 }
163185 }
164186}
0 commit comments