diff --git a/packages/core/js-client/src/api.ts b/packages/core/js-client/src/api.ts index 2544b522..c22f8f19 100644 --- a/packages/core/js-client/src/api.ts +++ b/packages/core/js-client/src/api.ts @@ -53,10 +53,20 @@ const isAquaConfig = ( * @param script - air script with function execution logic generated by the Aqua compiler */ export const v5_callFunction = async ( - args: (JSONValue | ServiceImpl[string])[], + args: [ + client: FluencePeer | (JSONValue | ServiceImpl[string]), + ...args: (JSONValue | ServiceImpl[string])[], + ], def: FunctionCallDef, script: string, ): Promise => { + const [peer, ...rest] = args; + + if (!(peer instanceof FluencePeer)) { + await v5_callFunction([getDefaultPeer(), ...rest], def, script); + return; + } + const argNames = Object.keys(def.arrow); const schemaArgCount = argNames.length; @@ -65,30 +75,15 @@ export const v5_callFunction = async ( const schemaFunctionArgs: Record = def.arrow.domain.tag === "nil" ? {} : def.arrow.domain.fields; - let peer: FluencePeer | undefined; - - if (args[0] instanceof FluencePeer) { - peer = args[0]; - args = args.slice(1); - } else { - peer = Fluence.defaultClient; - } - - if (peer == null) { - throw new Error( - "Could not register Aqua service because the client is not initialized. Did you forget to call Fluence.connect()?", - ); - } - // if args more than expected in schema (schemaArgCount) then last arg is config - const config = schemaArgCount < args.length ? args.pop() : undefined; + const config = schemaArgCount < rest.length ? rest.pop() : undefined; if (!isAquaConfig(config)) { throw new Error("Config should be object type"); } const callArgs = Object.fromEntries( - args.slice(0, schemaArgCount).map((arg, i) => { + rest.slice(0, schemaArgCount).map((arg, i) => { const argSchema = schemaFunctionArgs[argNames[i]]; if (argSchema.tag === "arrow") { @@ -133,44 +128,58 @@ export const v5_callFunction = async ( return aqua2ts(result, returnSchema); }; +const getDefaultPeer = (): FluencePeer => { + if (Fluence.defaultClient == null) { + throw new Error( + "Could not register Aqua service because the client is not initialized. Did you forget to call Fluence.connect()?", + ); + } + + return Fluence.defaultClient; +}; + +const getDefaultServiceId = (def: ServiceDef) => { + if (def.defaultServiceId == null) { + throw new Error("Service ID is not provided"); + } + + return def.defaultServiceId; +}; + +type RegisterServiceType = + | [ServiceImpl] + | [string, ServiceImpl] + | [FluencePeer, ServiceImpl] + | [FluencePeer, string, ServiceImpl]; + /** * Convenience function to support Aqua `service` generation backend * The compiler only need to generate a call the function and provide the corresponding definitions and the air script * @param args - raw arguments passed by user to the generated function * @param def - service definition generated by the Aqua compiler */ -export const v5_registerService = (args: unknown[], def: ServiceDef): void => { - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - const serviceImpl = args.pop() as ServiceImpl; - let peer: FluencePeer | undefined; - let serviceId = def.defaultServiceId; - - if (args[0] instanceof FluencePeer) { - peer = args[0]; - args = args.slice(1); - } else { - peer = Fluence.defaultClient; - } - - if (peer == null) { - throw new Error( - "Could not register Aqua service because the client is not initialized. Did you forget to call Fluence.connect()?", +export const v5_registerService = ( + args: RegisterServiceType, + def: ServiceDef, +): void => { + if (args.length === 1) { + v5_registerService( + [getDefaultPeer(), getDefaultServiceId(def), args[0]], + def, ); - } - if (args.length === 2) { - if (typeof args[0] !== "string") { - throw new Error( - `Service ID should be of type string. ${typeof args[0]} provided.`, - ); + return; + } else if (args.length === 2) { + if (args[0] instanceof FluencePeer) { + v5_registerService([args[0], getDefaultServiceId(def), args[1]], def); + return; + } else { + v5_registerService([getDefaultPeer(), args[0], args[1]], def); + return; } - - serviceId = args[0]; } - if (serviceId == null) { - throw new Error("Service ID is not provided"); - } + const [peer, serviceId, serviceImpl] = args; // Schema for every function in service const serviceSchema = def.functions.tag === "nil" ? {} : def.functions.fields;