@@ -22,7 +22,7 @@ export function createInitializer(getWasi, loadWasmModule, createClient) {
2222 /**
2323 * Convert Base64 to Base16 encoding
2424 */
25- base64ToHex : function ( base64 ) {
25+ base64ToHex : function ( base64 ) {
2626 if ( typeof atob === 'function' ) {
2727 const binary = atob ( base64 ) ;
2828 return [ ...binary ] . reduce ( ( hex , char ) => {
@@ -88,48 +88,73 @@ export function createInitializer(getWasi, loadWasmModule, createClient) {
8888 const apiInfo = await instance . exports . getApiInfo ( ) ;
8989 let makers = { } ;
9090 let cardanoApi = { objectType : "cardano-api" } ;
91+
9192 // Create maker functions for each virtual object type
93+
94+ function populateMethodOrGroup ( methodPopulator , methodOrGroup , target ) {
95+ if ( methodOrGroup . type === "method" ) {
96+ methodPopulator ( methodOrGroup . method , target ) ;
97+ } else if ( methodOrGroup . type === "group" ) {
98+ group = methodOrGroup . group ;
99+ target = target [ group . groupName ] = { } ;
100+ group . groupMethods . forEach ( methodOrGroup =>
101+ populateMethodOrGroup ( methodPopulator , methodOrGroup , target )
102+ ) ;
103+ }
104+ }
105+
106+ function populateDynamicMethod ( method , target ) {
107+ if ( method . return . type === "fluent" ) {
108+ // Fluent methods are synchronous and update the provider
109+ // A fluent method is one that returns the same object type
110+ target [ method . name ] = fixateArgs ( method . params , function ( ...args ) {
111+ const previousProvider = currentHaskellValueProvider ;
112+ // We update the provider so that it resolves the previous provider and chains the next call
113+ currentHaskellValueProvider = async ( ) => {
114+ const prevHaskellValue = await previousProvider ( ) ;
115+ return instance . exports [ method . name ] ( prevHaskellValue , ...args ) ;
116+ } ;
117+ return jsObject ; // Return current object for supporting chaining
118+ } ) ;
119+ } else {
120+ // Non-fluent methods (newObject or other) are async and apply the accumulated method calls
121+ target [ method . name ] = fixateArgs ( method . params , async function ( ...args ) {
122+ const haskellValue = await currentHaskellValueProvider ( ) ; // Resolve accumulated method calls
123+ const resultPromise = instance . exports [ method . name ] ( haskellValue , ...args ) ; // Call the non-fluent method
124+
125+ if ( method . return . type === "newObject" ) { // It returns a new object
126+ return makers [ method . return . objectType ] ( resultPromise ) ;
127+ } else { // It returns some primitive or other JS type (not a virtual object)
128+ return resultPromise ;
129+ }
130+ } ) ;
131+ }
132+ }
133+
92134 apiInfo . virtualObjects . forEach ( vo => {
93- makers [ vo . objectName ] = function ( initialHaskellValuePromise ) {
135+ makers [ vo . objectName ] = function ( initialHaskellValuePromise ) {
94136 // currentHaskellValueProvider is a function that returns a Promise for the Haskell value
95137 // It starts with the initial value promise and fluent methods accumulate transformations
96138 let currentHaskellValueProvider = ( ) => initialHaskellValuePromise ;
97139 let jsObject = { objectType : vo . objectName } ;
98140
99141 vo . methods . forEach ( method => {
100- if ( method . return . type === "fluent" ) {
101- // Fluent methods are synchronous and update the provider
102- // A fluent method is one that returns the same object type
103- jsObject [ method . name ] = fixateArgs ( method . params , function ( ...args ) {
104- const previousProvider = currentHaskellValueProvider ;
105- // We update the provider so that it resolves the previous provider and chains the next call
106- currentHaskellValueProvider = async ( ) => {
107- const prevHaskellValue = await previousProvider ( ) ;
108- return instance . exports [ method . name ] ( prevHaskellValue , ...args ) ;
109- } ;
110- return jsObject ; // Return current object for supporting chaining
111- } ) ;
112- } else {
113- // Non-fluent methods (newObject or other) are async and apply the accumulated method calls
114- jsObject [ method . name ] = fixateArgs ( method . params , async function ( ...args ) {
115- const haskellValue = await currentHaskellValueProvider ( ) ; // Resolve accumulated method calls
116- const resultPromise = instance . exports [ method . name ] ( haskellValue , ...args ) ; // Call the non-fluent method
117-
118- if ( method . return . type === "newObject" ) { // It returns a new object
119- return makers [ method . return . objectType ] ( resultPromise ) ;
120- } else { // It returns some primitive or other JS type (not a virtual object)
121- return resultPromise ;
122- }
123- } ) ;
124- }
142+ populateMethodOrGroup ( populateDynamicMethod , method , jsObject ) ;
125143 } ) ;
126144 return jsObject ;
127145 } ;
128146 } ) ;
129147
130148 // Populate the main API object with static methods
131- apiInfo . mainObject . methods . forEach ( method => {
132- cardanoApi [ method . name ] = async function ( ...args ) {
149+
150+ function populateStaticMethod ( method , target ) {
151+ target [ method . name ] = async function ( ...args ) {
152+ if ( method . group ) {
153+ if ( ! target [ method . group ] ) {
154+ target [ method . group ] = { } ;
155+ }
156+ target = target [ method . group ] ;
157+ }
133158 const resultPromise = instance . exports [ method . name ] ( ...args ) ;
134159
135160 if ( method . return . type === "newObject" ) { // Create a new object
@@ -138,6 +163,10 @@ export function createInitializer(getWasi, loadWasmModule, createClient) {
138163 return resultPromise ;
139164 }
140165 } ;
166+ }
167+
168+ apiInfo . mainObject . methods . forEach ( methodOrGroup => {
169+ populateMethodOrGroup ( populateStaticMethod , methodOrGroup , cardanoApi ) ;
141170 } ) ;
142171
143172 return cardanoApi ;
0 commit comments