Review fixes

This commit is contained in:
Akim Mamedov
2023-11-15 22:00:08 +07:00
parent bdf6644279
commit 12eea3122e
14 changed files with 374 additions and 292 deletions

View File

@ -34,10 +34,18 @@ for (const file of files) {
imports: [fileURLToPath(new URL("./node_modules", import.meta.url))], imports: [fileURLToPath(new URL("./node_modules", import.meta.url))],
}); });
if (cr.warnings.length > 0) {
console.log(cr.warnings);
}
if (cr.errors.length > 0) {
throw new Error(cr.errors.join("\n"));
}
const res = await aquaToJs(cr, "ts"); const res = await aquaToJs(cr, "ts");
if (res == null) { if (res == null) {
throw new Error(cr.errors.join("\n")); throw new Error("AquaToJs gave null value after compilation");
} }
await writeFile( await writeFile(

View File

@ -14,15 +14,17 @@
"keywords": [], "keywords": [],
"author": "Fluence Labs", "author": "Fluence Labs",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": {
"ts-pattern": "5.0.5"
},
"devDependencies": { "devDependencies": {
"@fluencelabs/aqua-api": "0.12.0", "@fluencelabs/aqua-api": "0.12.0",
"@fluencelabs/aqua-lib": "0.7.3", "@fluencelabs/aqua-lib": "0.7.3",
"@fluencelabs/interfaces": "workspace:*", "@fluencelabs/interfaces": "workspace:*",
"@fluencelabs/js-client": "workspace:^", "@fluencelabs/js-client": "0.4.3",
"@fluencelabs/registry": "0.8.7", "@fluencelabs/registry": "0.8.7",
"@fluencelabs/spell": "0.5.20", "@fluencelabs/spell": "0.5.20",
"@fluencelabs/trust-graph": "0.4.7", "@fluencelabs/trust-graph": "0.4.7",
"ts-pattern": "5.0.5",
"vitest": "0.34.6", "vitest": "0.34.6",
"zod": "3.22.4" "zod": "3.22.4"
} }

View File

@ -1,106 +0,0 @@
/**
* @typedef {import("@fluencelabs/js-client").NonArrowSimpleType} NonArrowSimpleType
* @typedef {import("@fluencelabs/js-client").JSONValue} JSONValue
*/
/**
* Convert value from its representation in aqua language to representation in typescript
* @param {JSONValue} value - value as represented in aqua
* @param {NonArrowSimpleType} schema - definition of the aqua schema
* @returns {JSONValue} value represented in typescript
*/
export function aqua2ts(value, schema) {
if (schema.tag === "nil") {
return null;
} else if (schema.tag === "option") {
if (!Array.isArray(value)) {
throw new Error("Bad schema");
}
if (value.length === 0) {
return null;
} else {
return aqua2ts(value[0], schema.type);
}
} else if (
schema.tag === "scalar" ||
schema.tag === "bottomType" ||
schema.tag === "topType"
) {
return value;
} else if (schema.tag === "array") {
if (!Array.isArray(value)) {
throw new Error("Bad schema");
}
return value.map((y) => {
return aqua2ts(y, schema.type);
});
} else if (schema.tag === "unlabeledProduct") {
if (!Array.isArray(value)) {
throw new Error("Bad schema");
}
return value.map((y, i) => {
return aqua2ts(y, schema.items[i]);
});
} else if (schema.tag === "struct" || schema.tag === "labeledProduct") {
if (typeof value !== "object" || value == null || Array.isArray(value)) {
throw new Error("Bad schema");
}
return Object.entries(schema.fields).reduce((agg, [key, type]) => {
const val = aqua2ts(value[key], type);
return { ...agg, [key]: val };
}, {});
} else {
throw new Error("Unexpected tag: " + JSON.stringify(schema));
}
}
/**
* Convert value from its typescript representation to representation in aqua
* @param value {JSONValue} the value as represented in typescript
* @param schema {NonArrowSimpleType} - definition of the aqua type
* @returns {JSONValue} represented in aqua
*/
export function ts2aqua(value, schema) {
if (schema.tag === "nil") {
return null;
} else if (schema.tag === "option") {
return value == null ? [] : [ts2aqua(value, schema.type)];
} else if (
schema.tag === "scalar" ||
schema.tag === "bottomType" ||
schema.tag === "topType"
) {
return value;
} else if (schema.tag === "array") {
if (!Array.isArray(value)) {
throw new Error("Bad schema");
}
return value.map((y) => {
return ts2aqua(y, schema.type);
});
} else if (schema.tag === "unlabeledProduct") {
if (!Array.isArray(value)) {
throw new Error("Bad schema");
}
return value.map((y, i) => {
return ts2aqua(y, schema.items[i]);
});
} else if (schema.tag === "struct" || schema.tag === "labeledProduct") {
if (typeof value !== "object" || value == null || Array.isArray(value)) {
throw new Error("Bad schema");
}
return Object.entries(schema.fields).reduce((agg, [key, type]) => {
const val = ts2aqua(value[key], type);
return { ...agg, [key]: val };
}, {});
} else {
throw new Error("Unexpected tag: " + JSON.stringify(schema));
}
}

View File

@ -29,60 +29,23 @@ export function generateFunctions(
.join("\n\n"); .join("\n\n");
} }
type DeepToType<T> = { [K in keyof T]: DeepToType<T[K]> };
function generateFunction(typeGenerator: TypeGenerator, func: AquaFunction) { function generateFunction(typeGenerator: TypeGenerator, func: AquaFunction) {
const funcDef: DeepToType<typeof func.funcDef> = func.funcDef;
const scriptConstName = func.funcDef.functionName + "_script"; const scriptConstName = func.funcDef.functionName + "_script";
const codomain = func.funcDef.arrow.codomain;
const valueSchema =
codomain.tag === "unlabeledProduct" && codomain.items.length === 1
? codomain.items[0]
: codomain;
const valueSchemaString = JSON.stringify(
recursiveRenameLaquaProps(valueSchema),
null,
4,
);
const domain = func.funcDef.arrow.domain;
const argNames = domain.tag === "nil" ? [] : Object.keys(domain.fields);
return `export const ${scriptConstName} = \` return `export const ${scriptConstName} = \`
${func.script}\`; ${func.script}\`;
${typeGenerator.funcType(func)} ${typeGenerator.funcType(func)}
export async function ${func.funcDef.functionName}(${typeGenerator.type( export function ${func.funcDef.functionName}(${typeGenerator.type(
"...args", "...args",
"any[]", "any[]",
)}) { )}) {
const argNames = [${argNames return callFunction$$(
.map((arg) => { args,
return `"${arg}"`; ${JSON.stringify(recursiveRenameLaquaProps(funcDef), null, 4)},
}) ${scriptConstName}
.join(", ")}];
const argCount = argNames.length;
let peer = undefined;
if (args[0] instanceof FluencePeer$$) {
peer = args[0];
args = args.slice(1);
}
const callArgs = Object.fromEntries(args.slice(0, argCount).map((arg, i) => [argNames[i], arg]));
const params = ({
peer,
args: callArgs,
config: args[argCount]
});
const result = await callFunction$$({
script: ${scriptConstName},
...params,
});
return aqua2ts(result,
${valueSchemaString}
); );
}`; }`;
} }

View File

@ -16,6 +16,8 @@
import { ServiceDef } from "@fluencelabs/interfaces"; import { ServiceDef } from "@fluencelabs/interfaces";
import { recursiveRenameLaquaProps } from "../utils.js";
import { TypeGenerator } from "./interfaces.js"; import { TypeGenerator } from "./interfaces.js";
export interface DefaultServiceId { export interface DefaultServiceId {
@ -40,45 +42,46 @@ function generateService(
srvName: string, srvName: string,
srvDef: ServiceDef, srvDef: ServiceDef,
) { ) {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const defaultServiceId = (srvDef.defaultServiceId as DefaultServiceId)
.s_Some__f_value;
return [ return [
typeGenerator.serviceType(srvName, srvDef), typeGenerator.serviceType(srvName, srvDef),
generateRegisterServiceOverload(typeGenerator, srvName, defaultServiceId), generateRegisterServiceOverload(typeGenerator, srvName, srvDef),
].join("\n"); ].join("\n");
} }
function generateRegisterServiceOverload( function generateRegisterServiceOverload(
typeGenerator: TypeGenerator, typeGenerator: TypeGenerator,
srvName: string, srvName: string,
srvDefaultId?: string, srvDef: ServiceDef,
) { ) {
return `export function register${srvName}(${typeGenerator.type( return [
`export function register${srvName}(${typeGenerator.type(
"...args", "...args",
"any[]", "any[]",
)}) { )}) {`,
const service = args.pop(); " registerService$$(",
const defaultServiceId = ${ " args,",
srvDefaultId != null ? `"${srvDefaultId}"` : "undefined" ` ${serviceToJson(srvDef)}`,
}; " );",
"}",
const params = args[0] instanceof FluencePeer$$ ? ({ ].join("\n");
peer: args[0], }
serviceId: args[1] ?? defaultServiceId
}) : ({ function serviceToJson(service: ServiceDef): string {
peer: undefined, return JSON.stringify(
serviceId: args[0] ?? defaultServiceId {
}); // This assertion is required because aqua-api gives bad types
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
if (params.serviceId == null) { ...((service.defaultServiceId as DefaultServiceId).s_Some__f_value != null
throw new Error("Service ID is not provided"); ? {
} defaultServiceId:
// This assertion is required because aqua-api gives bad types
registerService$$({ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
service, (service.defaultServiceId as DefaultServiceId).s_Some__f_value,
...params }
}); : {}),
}`; functions: recursiveRenameLaquaProps(service.functions),
},
null,
4,
);
} }

View File

@ -57,8 +57,7 @@
"rxjs": "7.5.5", "rxjs": "7.5.5",
"uint8arrays": "4.0.3", "uint8arrays": "4.0.3",
"uuid": "8.3.2", "uuid": "8.3.2",
"zod": "3.22.4", "zod": "3.22.4"
"zod-validation-error": "2.1.0"
}, },
"devDependencies": { "devDependencies": {
"@fluencelabs/aqua-api": "0.9.3", "@fluencelabs/aqua-api": "0.9.3",

View File

@ -14,77 +14,155 @@
* limitations under the License. * limitations under the License.
*/ */
import type { CallAquaFunctionArgs } from "./compilerSupport/callFunction.js"; import type {
FunctionCallDef,
JSONValue,
SimpleTypes,
ArrowWithoutCallbacks,
ServiceDef,
} from "@fluencelabs/interfaces";
import { CallAquaFunctionConfig } from "./compilerSupport/callFunction.js";
import {
aqua2ts,
ts2aqua,
wrapFunction,
wrapServiceFunction,
} from "./compilerSupport/conversions.js";
import { ServiceImpl } from "./compilerSupport/types.js"; import { ServiceImpl } from "./compilerSupport/types.js";
import { FluencePeer } from "./jsPeer/FluencePeer.js"; import { FluencePeer } from "./jsPeer/FluencePeer.js";
import { callAquaFunction, Fluence, registerService } from "./index.js"; import { callAquaFunction, Fluence, registerService } from "./index.js";
export const isFluencePeer = (
fluencePeerCandidate: unknown,
): fluencePeerCandidate is FluencePeer => {
return fluencePeerCandidate instanceof FluencePeer;
};
type CallAquaFunctionArgsTuned = Pick<CallAquaFunctionArgs, "args" | "script"> &
Partial<Pick<CallAquaFunctionArgs, "config" | "peer">>;
type RegisterServiceArgs = {
peer?: FluencePeer;
service: ServiceImpl;
serviceId: string;
};
/** /**
* Convenience function to support Aqua `func` generation backend * Convenience function to support Aqua `func` generation backend
* The compiler only need to generate a call the function and provide 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 def - function definition 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 (
config = {}, args: (JSONValue | ((...args: JSONValue[]) => JSONValue))[],
peer, def: FunctionCallDef,
args, script: string,
script, ): Promise<unknown> => {
}: CallAquaFunctionArgsTuned): Promise<unknown> => { const argNames = Object.keys(def.arrow);
const argCount = argNames.length;
const functionArgs: Record<string, SimpleTypes | ArrowWithoutCallbacks> =
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;
}
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const config =
argCount < args.length
? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
(args.pop() as CallAquaFunctionConfig | undefined)
: undefined;
if (peer == null) { if (peer == null) {
if (Fluence.defaultClient == null) {
throw new Error( throw new Error(
"Could not register Aqua service because the client is not initialized. Did you forget to call Fluence.connect()?", "Could not register Aqua service because the client is not initialized. Did you forget to call Fluence.connect()?",
); );
} }
peer = Fluence.defaultClient; const callArgs = Object.fromEntries<
JSONValue | ((...args: JSONValue[]) => JSONValue)
>(
args.slice(0, argCount).map((arg, i) => {
const argSchema = functionArgs[argNames[i]];
if (argSchema.tag === "arrow") {
if (typeof arg !== "function") {
throw new Error("Argument and schema doesn't match");
} }
return callAquaFunction({ const wrappedFunction = wrapFunction(arg, argSchema);
args,
script, return [argNames[i], wrappedFunction];
config, }
if (typeof arg === "function") {
throw new Error("Argument and schema doesn't match");
}
return [argNames[i], ts2aqua(arg, argSchema)];
}),
);
const params = {
peer, peer,
args: callArgs,
config,
};
const result = await callAquaFunction({
script,
...params,
}); });
const valueSchema =
def.arrow.codomain.tag === "unlabeledProduct" &&
def.arrow.codomain.items.length === 1
? def.arrow.codomain.items[0]
: def.arrow.codomain;
return aqua2ts(result, valueSchema);
}; };
/** /**
* 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 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 def - service definition generated by the Aqua compiler
*/ */
export const v5_registerService = ({ export const v5_registerService = (args: unknown[], def: ServiceDef): void => {
serviceId, // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
service, const serviceImpl = args.pop() as ServiceImpl;
peer, let peer: FluencePeer | undefined;
}: RegisterServiceArgs): void => { let serviceId = def.defaultServiceId;
if (args[0] instanceof FluencePeer) {
peer = args[0];
args = args.slice(1);
} else {
peer = Fluence.defaultClient;
}
if (peer == null) { if (peer == null) {
if (Fluence.defaultClient == null) {
throw new Error( throw new Error(
"Could not register Aqua service because the client is not initialized. Did you forget to call Fluence.connect()?", "Could not register Aqua service because the client is not initialized. Did you forget to call Fluence.connect()?",
); );
} }
peer = Fluence.defaultClient; if (typeof args[0] === "string") {
serviceId = args[0];
} }
if (serviceId == null) {
throw new Error("Service ID is not provided");
}
const serviceSchema = def.functions.tag === "nil" ? {} : def.functions.fields;
const wrappedServiceImpl = Object.fromEntries(
Object.entries(serviceImpl).map(([name, func]) => {
return [name, wrapServiceFunction(func, serviceSchema[name])];
}),
);
registerService({ registerService({
service, service: wrappedServiceImpl,
serviceId,
peer, peer,
serviceId,
}); });
}; };

View File

@ -17,7 +17,7 @@
import { JSONValue, NonArrowSimpleType } from "@fluencelabs/interfaces"; import { JSONValue, NonArrowSimpleType } from "@fluencelabs/interfaces";
import { it, describe, expect, test } from "vitest"; import { it, describe, expect, test } from "vitest";
import { aqua2ts, ts2aqua } from "../converters.js"; import { aqua2ts, ts2aqua } from "../conversions.js";
const i32 = { tag: "scalar", name: "i32" } as const; const i32 = { tag: "scalar", name: "i32" } as const;

View File

@ -17,7 +17,9 @@
import { JSONValue } from "@fluencelabs/interfaces"; import { JSONValue } from "@fluencelabs/interfaces";
import { FluencePeer } from "../jsPeer/FluencePeer.js"; import { FluencePeer } from "../jsPeer/FluencePeer.js";
import { ParticleContext } from "../jsServiceHost/interfaces.js";
import { logger } from "../util/logger.js"; import { logger } from "../util/logger.js";
import { ArgCallbackFunction } from "../util/testUtils.js";
import { import {
errorHandlingService, errorHandlingService,
@ -28,7 +30,6 @@ import {
ServiceDescription, ServiceDescription,
userHandlerService, userHandlerService,
} from "./services.js"; } from "./services.js";
import { ServiceImpl } from "./types.js";
const log = logger("aqua"); const log = logger("aqua");
@ -46,9 +47,9 @@ const log = logger("aqua");
export type CallAquaFunctionArgs = { export type CallAquaFunctionArgs = {
script: string; script: string;
config?: CallAquaFunctionConfig; config: CallAquaFunctionConfig | undefined;
peer: FluencePeer; peer: FluencePeer;
args: { [key: string]: JSONValue | ServiceImpl[string] }; args: { [key: string]: JSONValue | ArgCallbackFunction };
}; };
export type CallAquaFunctionConfig = { export type CallAquaFunctionConfig = {
@ -65,12 +66,21 @@ export const callAquaFunction = async ({
const particle = await peer.internals.createNewParticle(script, config.ttl); const particle = await peer.internals.createNewParticle(script, config.ttl);
return new Promise((resolve, reject) => { return new Promise<JSONValue>((resolve, reject) => {
for (const [name, argVal] of Object.entries(args)) { for (const [name, argVal] of Object.entries(args)) {
let service: ServiceDescription; let service: ServiceDescription;
if (typeof argVal === "function") { if (typeof argVal === "function") {
service = userHandlerService("callbackSrv", name, argVal); service = userHandlerService(
"callbackSrv",
name,
(...args: [...JSONValue[], ParticleContext]) => {
// Impossible to extract all element except the last one and coerce type
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const jsonArgs = args.slice(0, args.length - 1) as JSONValue[];
return argVal(jsonArgs);
},
);
} else { } else {
service = injectValueService("getDataSrv", name, argVal); service = injectValueService("getDataSrv", name, argVal);
} }

View File

@ -0,0 +1,166 @@
/**
* Copyright 2023 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
ArrowWithCallbacks,
ArrowWithoutCallbacks,
JSONValue,
NonArrowSimpleType,
} from "@fluencelabs/interfaces";
import { ParticleContext } from "../jsServiceHost/interfaces.js";
import { MaybePromise } from "./types.js";
export function aqua2ts(
value: JSONValue,
schema: NonArrowSimpleType,
): JSONValue {
if (schema.tag === "nil") {
return null;
} else if (schema.tag === "option") {
if (!Array.isArray(value)) {
throw new Error("Value and schema doesn't match");
}
if (value.length === 0) {
return null;
} else {
return aqua2ts(value[0], schema.type);
}
} else if (
schema.tag === "scalar" ||
schema.tag === "bottomType" ||
schema.tag === "topType"
) {
return value;
} else if (schema.tag === "array") {
if (!Array.isArray(value)) {
throw new Error("Value and schema doesn't match");
}
return value.map((y) => {
return aqua2ts(y, schema.type);
});
} else if (schema.tag === "unlabeledProduct") {
if (!Array.isArray(value)) {
throw new Error("Value and schema doesn't match");
}
return value.map((y, i) => {
return aqua2ts(y, schema.items[i]);
});
} else if (["labeledProduct", "struct"].includes(schema.tag)) {
if (typeof value !== "object" || value == null || Array.isArray(value)) {
throw new Error("Value and schema doesn't match");
}
return Object.entries(schema.fields).reduce((agg, [key, type]) => {
const val = aqua2ts(value[key], type);
return { ...agg, [key]: val };
}, {});
} else {
throw new Error("Unexpected tag: " + JSON.stringify(schema));
}
}
export function ts2aqua(
value: JSONValue,
schema: NonArrowSimpleType,
): JSONValue {
if (schema.tag === "nil") {
return null;
} else if (schema.tag === "option") {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return value == null ? [] : ([ts2aqua(value, schema.type)] as [JSONValue]);
} else if (
schema.tag === "scalar" ||
schema.tag === "bottomType" ||
schema.tag === "topType"
) {
return value;
} else if (schema.tag === "array") {
if (!Array.isArray(value)) {
throw new Error("Value and schema doesn't match");
}
return value.map((y) => {
return ts2aqua(y, schema.type);
});
} else if (schema.tag === "unlabeledProduct") {
if (!Array.isArray(value)) {
throw new Error("Value and schema doesn't match");
}
return value.map((y, i) => {
return ts2aqua(y, schema.items[i]);
});
} else if (["labeledProduct", "struct"].includes(schema.tag)) {
if (typeof value !== "object" || value == null || Array.isArray(value)) {
throw new Error("Value and schema doesn't match");
}
return Object.entries(schema.fields).reduce((agg, [key, type]) => {
const val = ts2aqua(value[key], type);
return { ...agg, [key]: val };
}, {});
} else {
throw new Error("Unexpected tag: " + JSON.stringify(schema));
}
}
export const wrapFunction = (
value: (...args: JSONValue[]) => JSONValue,
schema: ArrowWithoutCallbacks,
): ((...args: JSONValue[]) => JSONValue) => {
return (...args) => {
const schemaArgs =
schema.codomain.tag === "nil" ? [] : schema.codomain.items;
const tsArgs = args.map((arg, i) => {
return aqua2ts(arg, schemaArgs[i]);
});
const result = value(...tsArgs);
return ts2aqua(result, schema.codomain);
};
};
export const wrapServiceFunction = (
value: (
...args: [...JSONValue[], ParticleContext]
) => MaybePromise<JSONValue>,
schema: ArrowWithCallbacks,
): ((
...args: [...JSONValue[], ParticleContext]
) => MaybePromise<JSONValue>) => {
return async (...args) => {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const jsonArgs = args.slice(0, args.length - 1) as JSONValue[];
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const context = args[args.length - 1] as ParticleContext;
const schemaArgs =
schema.codomain.tag === "nil" ? [] : schema.codomain.items;
const tsArgs = jsonArgs.map((arg, i) => {
return aqua2ts(arg, schemaArgs[i]);
});
const result = await value(...tsArgs, context);
return ts2aqua(result, schema.codomain);
};
};

View File

@ -204,6 +204,4 @@ export {
export { FluencePeer } from "./jsPeer/FluencePeer.js"; export { FluencePeer } from "./jsPeer/FluencePeer.js";
export type { JSONValue, NonArrowSimpleType } from "@fluencelabs/interfaces";
export * from "./network.js"; export * from "./network.js";

View File

@ -16,36 +16,11 @@
import { it, describe, expect } from "vitest"; import { it, describe, expect } from "vitest";
import { isFluencePeer } from "../../api.js";
import { handleTimeout } from "../../particle/Particle.js"; import { handleTimeout } from "../../particle/Particle.js";
import { import { registerHandlersHelper, withPeer } from "../../util/testUtils.js";
mkTestPeer,
registerHandlersHelper,
withPeer,
} from "../../util/testUtils.js";
import { FluencePeer } from "../FluencePeer.js"; import { FluencePeer } from "../FluencePeer.js";
describe("FluencePeer usage test suite", () => { describe("FluencePeer usage test suite", () => {
it("should perform test for FluencePeer class correctly", async () => {
// arrange
const peer = await mkTestPeer();
const number = 1;
const object = { str: "Hello!" };
const undefinedVal = undefined;
// act
const isPeerPeer = isFluencePeer(peer);
const isNumberPeer = isFluencePeer(number);
const isObjectPeer = isFluencePeer(object);
const isUndefinedPeer = isFluencePeer(undefinedVal);
// act
expect(isPeerPeer).toBe(true);
expect(isNumberPeer).toBe(false);
expect(isObjectPeer).toBe(false);
expect(isUndefinedPeer).toBe(false);
});
it("Should successfully call identity on local peer", async function () { it("Should successfully call identity on local peer", async function () {
await withPeer(async (peer) => { await withPeer(async (peer) => {
const script = ` const script = `

View File

@ -30,10 +30,7 @@ import { ClientConfig, RelayOptions } from "../clientPeer/types.js";
import { callAquaFunction } from "../compilerSupport/callFunction.js"; import { callAquaFunction } from "../compilerSupport/callFunction.js";
import { IConnection } from "../connection/interfaces.js"; import { IConnection } from "../connection/interfaces.js";
import { DEFAULT_CONFIG, FluencePeer } from "../jsPeer/FluencePeer.js"; import { DEFAULT_CONFIG, FluencePeer } from "../jsPeer/FluencePeer.js";
import { import { CallServiceResultType } from "../jsServiceHost/interfaces.js";
CallServiceResultType,
ParticleContext,
} from "../jsServiceHost/interfaces.js";
import { JsServiceHost } from "../jsServiceHost/JsServiceHost.js"; import { JsServiceHost } from "../jsServiceHost/JsServiceHost.js";
import { WrapFnIntoServiceCall } from "../jsServiceHost/serviceUtils.js"; import { WrapFnIntoServiceCall } from "../jsServiceHost/serviceUtils.js";
import { KeyPair } from "../keypair/index.js"; import { KeyPair } from "../keypair/index.js";
@ -80,7 +77,7 @@ interface FunctionInfo {
* Type for callback passed as aqua function argument * Type for callback passed as aqua function argument
*/ */
export type ArgCallbackFunction = ( export type ArgCallbackFunction = (
...args: [...JSONValue[], ParticleContext] ...args: JSONValue[]
) => JSONValue | Promise<JSONValue>; ) => JSONValue | Promise<JSONValue>;
/** /**

23
pnpm-lock.yaml generated
View File

@ -161,6 +161,10 @@ importers:
version: 6.1.1 version: 6.1.1
packages/core/aqua-to-js: packages/core/aqua-to-js:
dependencies:
ts-pattern:
specifier: 5.0.5
version: 5.0.5
devDependencies: devDependencies:
'@fluencelabs/aqua-api': '@fluencelabs/aqua-api':
specifier: 0.12.0 specifier: 0.12.0
@ -172,7 +176,7 @@ importers:
specifier: workspace:* specifier: workspace:*
version: link:../interfaces version: link:../interfaces
'@fluencelabs/js-client': '@fluencelabs/js-client':
specifier: workspace:^ specifier: 0.4.3
version: link:../js-client version: link:../js-client
'@fluencelabs/registry': '@fluencelabs/registry':
specifier: 0.8.7 specifier: 0.8.7
@ -183,9 +187,6 @@ importers:
'@fluencelabs/trust-graph': '@fluencelabs/trust-graph':
specifier: 0.4.7 specifier: 0.4.7
version: 0.4.7 version: 0.4.7
ts-pattern:
specifier: 5.0.5
version: 5.0.5
vitest: vitest:
specifier: 0.34.6 specifier: 0.34.6
version: 0.34.6 version: 0.34.6
@ -291,9 +292,6 @@ importers:
zod: zod:
specifier: 3.22.4 specifier: 3.22.4
version: 3.22.4 version: 3.22.4
zod-validation-error:
specifier: 2.1.0
version: 2.1.0(zod@3.22.4)
devDependencies: devDependencies:
'@fluencelabs/aqua-api': '@fluencelabs/aqua-api':
specifier: 0.9.3 specifier: 0.9.3
@ -14060,7 +14058,7 @@ packages:
/ts-pattern@5.0.5: /ts-pattern@5.0.5:
resolution: {integrity: sha512-tL0w8U/pgaacOmkb9fRlYzWEUDCfVjjv9dD4wHTgZ61MjhuMt46VNWTG747NqW6vRzoWIKABVhFSOJ82FvXrfA==} resolution: {integrity: sha512-tL0w8U/pgaacOmkb9fRlYzWEUDCfVjjv9dD4wHTgZ61MjhuMt46VNWTG747NqW6vRzoWIKABVhFSOJ82FvXrfA==}
dev: true dev: false
/tsconfck@2.1.1(typescript@5.1.6): /tsconfck@2.1.1(typescript@5.1.6):
resolution: {integrity: sha512-ZPCkJBKASZBmBUNqGHmRhdhM8pJYDdOXp4nRgj/O0JwUwsMq50lCDRQP/M5GBNAA0elPrq4gAeu4dkaVCuKWww==} resolution: {integrity: sha512-ZPCkJBKASZBmBUNqGHmRhdhM8pJYDdOXp4nRgj/O0JwUwsMq50lCDRQP/M5GBNAA0elPrq4gAeu4dkaVCuKWww==}
@ -15220,14 +15218,5 @@ packages:
engines: {node: '>=12.20'} engines: {node: '>=12.20'}
dev: true dev: true
/zod-validation-error@2.1.0(zod@3.22.4):
resolution: {integrity: sha512-VJh93e2wb4c3tWtGgTa0OF/dTt/zoPCPzXq4V11ZjxmEAFaPi/Zss1xIZdEB5RD8GD00U0/iVXgqkF77RV7pdQ==}
engines: {node: '>=18.0.0'}
peerDependencies:
zod: ^3.18.0
dependencies:
zod: 3.22.4
dev: false
/zod@3.22.4: /zod@3.22.4:
resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}