@@ -42,13 +42,128 @@ export const ConfigView = () => {
4242 } , [ klasses , options , memory . klasses , memory . options ] ) ;
4343
4444 const onSave = useCallback ( ( ) => {
45+ // Track if useStringAsObject option changed
46+ const stringAsObjectChanged = options . useStringAsObject !== memory . options . useStringAsObject ;
47+
4548 // Update existing objects to match new class definitions
4649 const updatedObjects = { ...memory . objects } ;
50+ const updatedMethodCalls = { ...memory . methodCalls } ;
51+ const updatedVariables = { ...memory . variables } ;
52+
53+ // Helper function to generate unique ID
54+ const generateId = ( ) => `@${ Math . random ( ) . toString ( 36 ) . slice ( 2 , 18 ) } ` ;
55+
56+ // Convert String values to String objects or vice versa
57+ if ( stringAsObjectChanged ) {
58+ if ( options . useStringAsObject ) {
59+ // Converting TO String objects mode
60+ console . log ( "Converting string primitives to String objects" ) ;
61+
62+ // Convert string attributes in objects
63+ Object . entries ( updatedObjects ) . forEach ( ( [ _ , obj ] ) => {
64+ Object . entries ( obj . attributes ) . forEach ( ( [ attrName , attr ] ) => {
65+ if ( attr . dataType === "String" && attr . value && typeof attr . value === "string" && ! attr . value . startsWith ( "@" ) ) {
66+ // Create a new String object
67+ const stringObjId = generateId ( ) ;
68+ updatedObjects [ stringObjId ] = {
69+ klass : "String" ,
70+ attributes : {
71+ value : {
72+ dataType : "String" ,
73+ value : attr . value ,
74+ } ,
75+ } ,
76+ position : {
77+ x : obj . position . x + 200 ,
78+ y : obj . position . y ,
79+ } ,
80+ } ;
81+ // Update the attribute to reference the String object
82+ obj . attributes [ attrName ] = {
83+ dataType : "String" ,
84+ value : stringObjId ,
85+ } ;
86+ }
87+ } ) ;
88+ } ) ;
89+
90+ // Convert string local variables in method calls
91+ Object . entries ( updatedMethodCalls ) . forEach ( ( [ _ , call ] ) => {
92+ Object . entries ( call . localVariables ) . forEach ( ( [ varName , variable ] ) => {
93+ if ( variable . dataType === "String" && variable . value && typeof variable . value === "string" && ! variable . value . startsWith ( "@" ) ) {
94+ // Create a new String object
95+ const stringObjId = generateId ( ) ;
96+ updatedObjects [ stringObjId ] = {
97+ klass : "String" ,
98+ attributes : {
99+ value : {
100+ dataType : "String" ,
101+ value : variable . value ,
102+ } ,
103+ } ,
104+ position : {
105+ x : call . position . x + 200 ,
106+ y : call . position . y ,
107+ } ,
108+ } ;
109+ // Update the variable to reference the String object
110+ call . localVariables [ varName ] = {
111+ dataType : "String" ,
112+ value : stringObjId ,
113+ } ;
114+ }
115+ } ) ;
116+ } ) ;
117+
118+ } else {
119+ // Converting FROM String objects mode TO primitives
120+ console . log ( "Converting String objects to string primitives" ) ;
121+
122+ // Find all String objects and extract their values
123+ const stringObjects : Record < string , string > = { } ;
124+ Object . entries ( updatedObjects ) . forEach ( ( [ objId , obj ] ) => {
125+ if ( obj . klass === "String" && obj . attributes . value ) {
126+ stringObjects [ objId ] = String ( obj . attributes . value . value || "" ) ;
127+ }
128+ } ) ;
129+
130+ // Convert string references in object attributes back to primitives
131+ Object . entries ( updatedObjects ) . forEach ( ( [ _ , obj ] ) => {
132+ Object . entries ( obj . attributes ) . forEach ( ( [ attrName , attr ] ) => {
133+ if ( attr . dataType === "String" && attr . value && typeof attr . value === "string" && attr . value . startsWith ( "@" ) ) {
134+ const stringValue = stringObjects [ attr . value ] || "" ;
135+ obj . attributes [ attrName ] = {
136+ dataType : "String" ,
137+ value : stringValue ,
138+ } ;
139+ }
140+ } ) ;
141+ } ) ;
142+
143+ // Convert string references in method call local variables back to primitives
144+ Object . entries ( updatedMethodCalls ) . forEach ( ( [ _ , call ] ) => {
145+ Object . entries ( call . localVariables ) . forEach ( ( [ varName , variable ] ) => {
146+ if ( variable . dataType === "String" && variable . value && typeof variable . value === "string" && variable . value . startsWith ( "@" ) ) {
147+ const stringValue = stringObjects [ variable . value ] || "" ;
148+ call . localVariables [ varName ] = {
149+ dataType : "String" ,
150+ value : stringValue ,
151+ } ;
152+ }
153+ } ) ;
154+ } ) ;
155+
156+ // Remove all String objects
157+ Object . keys ( stringObjects ) . forEach ( objId => {
158+ delete updatedObjects [ objId ] ;
159+ } ) ;
160+ }
161+ }
47162
48163 Object . entries ( updatedObjects ) . forEach ( ( [ objId , obj ] ) => {
49164 const klassDefinition = klasses [ obj . klass ] ;
50165
51- // Skip if class doesn't exist (e.g., Array) or object class is not in klasses
166+ // Skip if class doesn't exist (e.g., Array, String ) or object class is not in klasses
52167 if ( ! klassDefinition ) return ;
53168
54169 const updatedAttributes = { ...obj . attributes } ;
@@ -83,6 +198,8 @@ export const ConfigView = () => {
83198 klasses,
84199 options,
85200 objects : updatedObjects ,
201+ methodCalls : updatedMethodCalls ,
202+ variables : updatedVariables ,
86203 } ) ;
87204 setHasUnsavedChanges ( false ) ;
88205 setShowSaveSuccess ( true ) ;
0 commit comments