This commit is contained in:
Akim Mamedov 2023-11-16 22:12:40 +07:00
parent ec830bca76
commit 20edd89456

View File

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