@@ -24,6 +24,8 @@ corePckg.data.filter(l => !!l.type).forEach((l, i) => {
2424 corePckgIds [ l . id ] = i + 1 ;
2525} ) ;
2626
27+ const random = ( ) => Math . random ( ) . toString ( 36 ) . slice ( 2 , 7 ) ;
28+
2729export const _ids = {
2830 '@deep-foundation/core' : corePckgIds ,
2931} ;
@@ -139,9 +141,9 @@ export const pathToWhere = (start: (DeepClientStartItem), ...path: DeepClientPat
139141 return where ;
140142}
141143
142- export const serializeWhere = ( exp : any , env : string = 'links' ) : any => {
144+ export const serializeWhere = ( exp : any , env : string = 'links' , unvertualizeId : ( id : number ) => number = defaultUnvertualizeId ) : any => {
143145 // if exp is array - map
144- if ( Object . prototype . toString . call ( exp ) === '[object Array]' ) return exp . map ( ( e ) => serializeWhere ( e , env ) ) ;
146+ if ( Object . prototype . toString . call ( exp ) === '[object Array]' ) return exp . map ( ( e ) => serializeWhere ( e , env , unvertualizeId ) ) ;
145147 else if ( typeof ( exp ) === 'object' ) {
146148 // if object
147149 const keys = Object . keys ( exp ) ;
@@ -162,26 +164,27 @@ export const serializeWhere = (exp: any, env: string = 'links'): any => {
162164 setted = result [ type ] = { value : { _eq : exp [ key ] } } ;
163165 } else {
164166 // else just equal
165- setted = result [ key ] = { _eq : exp [ key ] } ;
167+ setted = result [ key ] = { _eq : unvertualizeId ( exp [ key ] ) } ;
166168 }
167169 } else if ( ! _boolExpFields [ key ] && Object . prototype . toString . call ( exp [ key ] ) === '[object Array]' ) {
168170 // if field is not boolExp (_and _or _not) but contain array
169171 // @ts -ignore
170- setted = result [ key ] = serializeWhere ( pathToWhere ( ...exp [ key ] ) ) ;
172+ setted = result [ key ] = serializeWhere ( pathToWhere ( ...exp [ key ] ) , 'links' , unvertualizeId ) ;
171173 }
172174 } else if ( env === 'tree' ) {
173175 // if field contain primitive type - string/number
174176 if ( type === 'string' || type === 'number' ) {
175- setted = result [ key ] = { _eq : exp [ key ] } ;
177+ const isId = key === 'link_id' || key === 'tree_id' || key === 'root_id' || key === 'parent_id' ;
178+ setted = result [ key ] = { _eq : isId ? unvertualizeId ( exp [ key ] ) : exp [ key ] } ;
176179 } else if ( ! _boolExpFields [ key ] && Object . prototype . toString . call ( exp [ key ] ) === '[object Array]' ) {
177180 // if field is not boolExp (_and _or _not) but contain array
178181 // @ts -ignore
179- setted = result [ key ] = serializeWhere ( pathToWhere ( ...exp [ key ] ) ) ;
182+ setted = result [ key ] = serializeWhere ( pathToWhere ( ...exp [ key ] ) , 'links' , unvertualizeId ) ;
180183 }
181184 } else if ( env === 'value' ) {
182185 // if this is value
183186 if ( type === 'string' || type === 'number' ) {
184- setted = result [ key ] = { _eq : exp [ key ] } ;
187+ setted = result [ key ] = { _eq : key === 'link_id' ? unvertualizeId ( exp [ key ] ) : exp [ key ] } ;
185188 }
186189 }
187190 if ( type === 'object' && exp [ key ] . hasOwnProperty ( '_type_of' ) && (
@@ -192,7 +195,7 @@ export const serializeWhere = (exp: any, env: string = 'links'): any => {
192195 ( env === 'value' && key === 'link_id' )
193196 ) ) {
194197 // if field is object, and contain _type_od
195- const _temp = setted = { _by_item : { path_item_id : { _eq : exp [ key ] . _type_of } , group_id : { _eq : 0 } } } ;
198+ const _temp = setted = { _by_item : { path_item_id : { _eq : unvertualizeId ( exp [ key ] . _type_of ) } , group_id : { _eq : _ids [ '@deep-foundation/core' ] . typesTree } } } ;
196199 if ( key === 'id' ) {
197200 result . _and = result . _and ? [ ...result . _and , _temp ] : [ _temp ] ;
198201 } else {
@@ -205,8 +208,9 @@ export const serializeWhere = (exp: any, env: string = 'links'): any => {
205208 ( env === 'tree' && ! ! ~ [ 'link_id' , 'tree_id' , 'root_id' , 'parent_id' ] . indexOf ( key ) ) ||
206209 ( env === 'value' && key === 'link_id' )
207210 ) && Object . prototype . toString . call ( exp [ key ] . _id ) === '[object Array]' && exp [ key ] . _id . length >= 1 ) {
208- // if field is object, and contain _type_od
209- const _temp = setted = serializeWhere ( pathToWhere ( exp [ key ] . _id [ 0 ] , ...exp [ key ] . _id . slice ( 1 ) ) , 'links' ) ;
211+ const root = exp [ key ] . _id [ 0 ] ;
212+ // if field is object, and contain _type_of
213+ const _temp = setted = serializeWhere ( pathToWhere ( typeof ( root ) === 'number' ? unvertualizeId ( root ) : root , ...exp [ key ] . _id . slice ( 1 ) ) , 'links' , unvertualizeId ) ;
210214 if ( key === 'id' ) {
211215 result . _and = result . _and ? [ ...result . _and , _temp ] : [ _temp ] ;
212216 } else {
@@ -220,13 +224,13 @@ export const serializeWhere = (exp: any, env: string = 'links'): any => {
220224 _boolExpFields [ key ]
221225 ) ? (
222226 // just parse each item in array
223- serializeWhere ( exp [ key ] , env )
227+ serializeWhere ( exp [ key ] , env , unvertualizeId )
224228 ) : (
225229 // if we know context
226230 _serialize ?. [ env ] ?. relations ?. [ key ]
227231 ) ? (
228232 // go to this context then
229- serializeWhere ( exp [ key ] , _serialize ?. [ env ] ?. relations ?. [ key ] )
233+ serializeWhere ( exp [ key ] , _serialize ?. [ env ] ?. relations ?. [ key ] , unvertualizeId )
230234 ) : (
231235 // else just stop
232236 exp [ key ]
@@ -242,10 +246,12 @@ export const serializeWhere = (exp: any, env: string = 'links'): any => {
242246 }
243247} ;
244248
245- export const serializeQuery = ( exp : any , env : string = 'links' ) : any => {
249+ const defaultUnvertualizeId = ( id ) => id ;
250+
251+ export const serializeQuery = ( exp : any , env : string = 'links' , unvertualizeId = defaultUnvertualizeId ) : any => {
246252 const { limit, order_by, offset, distinct_on, ...where } = exp ;
247- const result : any = { where : typeof ( exp ) === 'object' ? Object . prototype . toString . call ( exp ) === '[object Array]' ? { id : { _in : exp } } : serializeWhere ( where , env ) : { id : { _eq : exp } } } ;
248- // const result: any = { where: serializeWhere(where, env) };
253+ const result : any = { where : typeof ( exp ) === 'object' ? Object . prototype . toString . call ( exp ) === '[object Array]' ? { id : { _in : exp . map ( id => unvertualizeId ( id ) ) } } : serializeWhere ( where , env , unvertualizeId ) : { id : { _eq : unvertualizeId ( exp ) } } } ;
254+ // const result: any = { where: serializeWhere(where, env, unvertualizeId ) };
249255 if ( limit ) result . limit = limit ;
250256 if ( order_by ) result . order_by = order_by ;
251257 if ( offset ) result . offset = offset ;
@@ -351,7 +357,8 @@ export interface DeepClientInstance<L = Link<number>> {
351357
352358
353359 serializeWhere ( exp : any , env ?: string ) : any ;
354- serializeQuery ( exp : any , env ?: string ) : any ;
360+ serializeQuery ( exp : any , env ?: string , unvertualizeId ?: ( id : number ) => number ) : any ;
361+ unvertualizeId ( id : number ) : number ;
355362
356363 id ( start : DeepClientStartItem | QueryLink , ...path : DeepClientPathItem [ ] ) : Promise < number > ;
357364 idLocal ( start : DeepClientStartItem , ...path : DeepClientPathItem [ ] ) : number ;
@@ -474,6 +481,69 @@ export function checkAndFillShorts(obj) {
474481 }
475482}
476483
484+ export function convertDeepInsertToMinilinksApply ( deep , objects , table , result : { id ?: number ; from_id ?: number ; to_id ?: number ; type_id ?: number ; value ?: any } [ ] = [ ] ) : void {
485+ if ( table === 'links' ) {
486+ for ( let i = 0 ; i < objects . length ; i ++ ) {
487+ const o = objects [ i ] ;
488+ let id = o . id ;
489+ if ( ! id ) {
490+ id = deep . minilinks . virtualCounter -- ;
491+ // @ts -ignore
492+ deep . minilinks ?. byId [ id ] ?. _id = apply ;
493+ }
494+ result . push ( {
495+ id : o . id || id , from_id : o . from_id , to_id : o . to_id , type_id : o . type_id ,
496+ value : o . string ?. data || o . number ?. data || o . object ?. data ,
497+ } ) ;
498+ if ( o ?. from ) convertDeepInsertToMinilinksApply ( deep , [ o ?. from ?. data ] , table , result ) ;
499+ if ( o ?. to ) convertDeepInsertToMinilinksApply ( deep , [ o ?. to ?. data ] , table , result ) ;
500+ if ( o ?. type ) convertDeepInsertToMinilinksApply ( deep , [ o ?. type ?. data ] , table , result ) ;
501+ if ( o ?. out ) convertDeepInsertToMinilinksApply ( deep , ( o ?. out ?. data ?. length ? o ?. out ?. data : [ o ?. out ?. data ] ) . map ( l => ( { ...l , from_id : id } ) ) , table , result ) ;
502+ if ( o ?. in ) convertDeepInsertToMinilinksApply ( deep , ( o ?. in ?. data ?. length ? o ?. in ?. data : [ o ?. in ?. data ] ) . map ( l => ( { ...l , to_id : id } ) ) , table , result ) ;
503+ if ( o ?. types ) convertDeepInsertToMinilinksApply ( deep , ( o ?. types ?. data ?. length ? o ?. types ?. data : [ o ?. types ?. data ] ) . map ( l => ( { ...l , type_id : id } ) ) , table , result ) ;
504+ }
505+ }
506+ }
507+
508+ export function convertDeepUpdateToMinilinksApply ( ml , _exp , _set , table , toUpdate : { id ?: number ; from_id ?: number ; to_id ?: number ; type_id ?: number ; value ?: any } [ ] = [ ] ) : void {
509+ if ( table === 'links' ) {
510+ try {
511+ const founded = ml . query ( _exp ) ;
512+ for ( let f of founded ) {
513+ toUpdate . push ( {
514+ id : f . id , from_id : f . from_id , to_id : f . to_id , type_id : f . type_id ,
515+ value : f . value ,
516+ ..._set
517+ } ) ;
518+ }
519+ } catch ( e ) { }
520+ } else if ( table === 'strings' || table === 'numbers' || table === 'objects' ) {
521+ const key = table . slice ( 0 , - 1 ) ;
522+ const founded = ml . query ( { [ key ] : _exp } ) ;
523+ for ( let f of founded ) {
524+ toUpdate . push ( {
525+ id : f . id , from_id : f . from_id , to_id : f . to_id , type_id : f . type_id ,
526+ value : { ...f ?. value , value : _set . value } ,
527+ } ) ;
528+ }
529+ }
530+ }
531+
532+ export function convertDeepDeleteToMinilinksApply ( ml , _exp , table , toDelete : number [ ] = [ ] , toUpdate : { id ?: number ; from_id ?: number ; to_id ?: number ; type_id ?: number ; value ?: any } [ ] = [ ] ) : void {
533+ if ( table === 'links' ) {
534+ try {
535+ const founded = ml . query ( _exp ) ;
536+ toDelete . push ( ...founded . map ( l => l . id ) ) ;
537+ } catch ( e ) { }
538+ } else if ( table === 'strings' || table === 'numbers' || table === 'objects' ) {
539+ const key = table . slice ( 0 , - 1 ) ;
540+ const founded = ml . query ( { [ key ] : _exp } ) ;
541+ toUpdate . push ( ...founded . map ( o => ( {
542+ id : o . id , from_id : o . from_id , to_id : o . to_id , type_id : o . type_id ,
543+ } ) ) ) ;
544+ }
545+ }
546+
477547export class DeepClient < L = Link < number > > implements DeepClientInstance < L > {
478548 static resolveDependency ?: ( path : string ) => Promise < any >
479549
@@ -538,6 +608,10 @@ export class DeepClient<L = Link<number>> implements DeepClientInstance<L> {
538608
539609 // @ts -ignore
540610 this . minilinks = options . minilinks || new MinilinkCollection ( ) ;
611+ this . unvertualizeId = ( id : number ) : number => {
612+ // @ts -ignore
613+ return this . minilinks . virtual . hasOwnProperty ( id ) ? this . minilinks . virtual [ id ] : id ;
614+ } ;
541615 this . table = options . table || 'links' ;
542616
543617 this . token = options . token ;
@@ -589,12 +663,13 @@ export class DeepClient<L = Link<number>> implements DeepClientInstance<L> {
589663
590664 serializeQuery = serializeQuery ;
591665 serializeWhere = serializeWhere ;
666+ unvertualizeId : ( id : number ) => number ;
592667
593668 async select < TTable extends 'links' | 'numbers' | 'strings' | 'objects' | 'can' | 'selectors' | 'tree' | 'handlers' , LL = L > ( exp : Exp < TTable > , options ?: ReadOptions < TTable > ) : Promise < DeepClientResult < LL [ ] > > {
594669 if ( ! exp ) {
595670 return { error : { message : '!exp' } , data : undefined , loading : false , networkStatus : undefined } ;
596671 }
597- const query = serializeQuery ( exp , options ?. table || 'links' ) ;
672+ const query = serializeQuery ( exp , options ?. table || 'links' , this . unvertualizeId ) ;
598673 const table = options ?. table || this . table ;
599674 const returning = options ?. returning ??
600675 ( table === 'links' ? this . linksSelectReturning :
@@ -635,7 +710,13 @@ export class DeepClient<L = Link<number>> implements DeepClientInstance<L> {
635710 const variables = options ?. variables ;
636711 const name = options ?. name || this . defaultInsertName ;
637712 let q : any = { } ;
638-
713+
714+ if ( this . minilinks ) {
715+ const toApply : any = [ ] ;
716+ convertDeepInsertToMinilinksApply ( this , _objects , table , toApply ) ;
717+ this . minilinks . add ( toApply ) ;
718+ }
719+
639720 try {
640721 q = await this . apolloClient . mutate ( generateSerial ( {
641722 actions : [ insertMutation ( table , { ...variables , objects : _objects } , { tableName : table , operation : 'insert' , returning } ) ] ,
@@ -646,7 +727,7 @@ export class DeepClient<L = Link<number>> implements DeepClientInstance<L> {
646727 if ( sqlError ?. message ) e . message = sqlError . message ;
647728 if ( ! this . _silent ( options ) ) throw new Error ( `DeepClient Insert Error: ${ e . message } ` , { cause : e } )
648729 return { ...q , data : ( q ) ?. data ?. m0 ?. returning , error : e } ;
649- }
730+ }
650731
651732 // @ts -ignore
652733 return { ...q , data : ( q ) ?. data ?. m0 ?. returning } ;
@@ -656,8 +737,15 @@ export class DeepClient<L = Link<number>> implements DeepClientInstance<L> {
656737 if ( exp === null ) return this . insert ( [ value ] , options ) ;
657738 if ( value === null ) return this . delete ( exp , options ) ;
658739
659- const query = serializeQuery ( exp , options ?. table === this . table || ! options ?. table ? 'links' : 'value' ) ;
740+ const query = serializeQuery ( exp , options ?. table === this . table || ! options ?. table ? 'links' : 'value' , this . unvertualizeId ) ;
660741 const table = options ?. table || this . table ;
742+
743+ if ( this . minilinks ) {
744+ const toUpdate : any = [ ] ;
745+ convertDeepUpdateToMinilinksApply ( this . minilinks , exp , value , table , toUpdate ) ;
746+ this . minilinks . update ( toUpdate ) ;
747+ }
748+
661749 const returning = options ?. returning || this . updateReturning ;
662750 const variables = options ?. variables ;
663751 const name = options ?. name || this . defaultUpdateName ;
@@ -673,18 +761,28 @@ export class DeepClient<L = Link<number>> implements DeepClientInstance<L> {
673761 if ( ! this . _silent ( options ) ) throw new Error ( `DeepClient Update Error: ${ e . message } ` , { cause : e } ) ;
674762 return { ...q , data : ( q ) ?. data ?. m0 ?. returning , error : e } ;
675763 }
764+
676765 // @ts -ignore
677766 return { ...q , data : ( q ) ?. data ?. m0 ?. returning } ;
678767 } ;
679768
680769 async delete < TTable extends 'links' | 'numbers' | 'strings' | 'objects' > ( exp : Exp < TTable > , options ?: WriteOptions < TTable > ) :Promise < DeepClientResult < { id } [ ] > > {
681770 if ( ! exp ) throw new Error ( '!exp' ) ;
682- const query = serializeQuery ( exp , options ?. table === this . table || ! options ?. table ? 'links' : 'value' ) ;
771+ const query = serializeQuery ( exp , options ?. table === this . table || ! options ?. table ? 'links' : 'value' , this . unvertualizeId ) ;
683772 const table = options ?. table || this . table ;
684773 const returning = options ?. returning || this . deleteReturning ;
685774 const variables = options ?. variables ;
686775 const name = options ?. name || this . defaultDeleteName ;
687776 let q ;
777+
778+ if ( this . minilinks ) {
779+ const toDelete : any = [ ] ;
780+ const toUpdate : any = [ ] ;
781+ convertDeepDeleteToMinilinksApply ( this . minilinks , exp , table , toDelete , toUpdate ) ;
782+ this . minilinks . update ( toUpdate ) ;
783+ this . minilinks . remove ( toDelete ) ;
784+ }
785+
688786 try {
689787 q = await this . apolloClient . mutate ( generateSerial ( {
690788 actions : [ deleteMutation ( table , { ...variables , ...query , returning } , { tableName : table , operation : 'delete' , returning } ) ] ,
@@ -697,6 +795,7 @@ export class DeepClient<L = Link<number>> implements DeepClientInstance<L> {
697795 if ( ! this . _silent ( options ) ) throw new Error ( `DeepClient Delete Error: ${ e . message } ` , { cause : e } ) ;
698796 return { ...q , data : ( q ) ?. data ?. m0 ?. returning , error : e } ;
699797 }
798+
700799 return { ...q , data : ( q ) ?. data ?. m0 ?. returning } ;
701800 } ;
702801
@@ -730,15 +829,15 @@ export class DeepClient<L = Link<number>> implements DeepClientInstance<L> {
730829 const newSerialActions : IGenerateMutationBuilder [ ] = updateOperations . map ( operation => {
731830 const exp = operation . exp ;
732831 const value = operation . value ;
733- const query = serializeQuery ( exp , table === this . table || ! table ? 'links' : 'value' ) ;
832+ const query = serializeQuery ( exp , table === this . table || ! table ? 'links' : 'value' , this . unvertualizeId ) ;
734833 return updateMutation ( table , { ...query , _set : value } , { tableName : table , operation : operationType , returning} )
735834 } )
736835 serialActions = [ ...serialActions , ...newSerialActions ] ;
737836 } else if ( operationType === 'delete' ) {
738837 const deleteOperations = operations as Array < SerialOperation < 'delete' , Table < 'delete' > > > ; ;
739838 const newSerialActions : IGenerateMutationBuilder [ ] = deleteOperations . map ( operation => {
740839 const exp = operation . exp ;
741- const query = serializeQuery ( exp , table === this . table || ! table ? 'links' : 'value' ) ;
840+ const query = serializeQuery ( exp , table === this . table || ! table ? 'links' : 'value' , this . unvertualizeId ) ;
742841 return deleteMutation ( table , { ...query } , { tableName : table , operation : operationType , returning } )
743842 } )
744843 serialActions = [ ...serialActions , ...newSerialActions ] ;
@@ -1070,11 +1169,11 @@ export function useDeepQuery<Table extends 'links'|'numbers'|'strings'|'objects'
10701169 error ?: any ;
10711170 loading : boolean ;
10721171} {
1073- const [ miniName ] = useState ( options ?. mini || Math . random ( ) . toString ( 36 ) . slice ( 2 , 7 ) ) ;
1172+ const [ miniName ] = useState ( options ?. mini || random ( ) ) ;
10741173 debug ( 'useDeepQuery' , miniName , query , options ) ;
10751174 const deep = useDeep ( ) ;
10761175 const wq = useMemo ( ( ) => {
1077- const sq = serializeQuery ( query ) ;
1176+ const sq = serializeQuery ( query , 'links' , deep . unvertualizeId ) ;
10781177 return generateQuery ( {
10791178 operation : 'query' ,
10801179 queries : [ generateQueryData ( {
@@ -1114,7 +1213,7 @@ export function useDeepSubscription<Table extends 'links'|'numbers'|'strings'|'o
11141213 debug ( 'useDeepSubscription' , miniName , query , options ) ;
11151214 const deep = useDeep ( ) ;
11161215 const wq = useMemo ( ( ) => {
1117- const sq = serializeQuery ( query ) ;
1216+ const sq = serializeQuery ( query , 'links' , deep . unvertualizeId ) ;
11181217 return generateQuery ( {
11191218 operation : 'subscription' ,
11201219 queries : [ generateQueryData ( {
0 commit comments