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 [
"...args", `export function register${srvName}(${typeGenerator.type(
"any[]", "...args",
)}) { "any[]",
const service = args.pop(); )}) {`,
const defaultServiceId = ${ " registerService$$(",
srvDefaultId != null ? `"${srvDefaultId}"` : "undefined" " args,",
}; ` ${serviceToJson(srvDef)}`,
" );",
const params = args[0] instanceof FluencePeer$$ ? ({ "}",
peer: args[0], ].join("\n");
serviceId: args[1] ?? defaultServiceId }
}) : ({
peer: undefined, function serviceToJson(service: ServiceDef): string {
serviceId: args[0] ?? defaultServiceId return JSON.stringify(
}); {
// This assertion is required because aqua-api gives bad types
if (params.serviceId == null) { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
throw new Error("Service ID is not provided"); ...((service.defaultServiceId as DefaultServiceId).s_Some__f_value != null
} ? {
defaultServiceId:
registerService$$({ // This assertion is required because aqua-api gives bad types
service, // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
...params (service.defaultServiceId as DefaultServiceId).s_Some__f_value,
}); }
}`; : {}),
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);
if (peer == null) { const argCount = argNames.length;
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()?",
);
}
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; peer = Fluence.defaultClient;
} }
return callAquaFunction({ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
args, const config =
script, argCount < args.length
config, ? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
(args.pop() as CallAquaFunctionConfig | undefined)
: undefined;
if (peer == null) {
throw new Error(
"Could not register Aqua service because the client is not initialized. Did you forget to call Fluence.connect()?",
);
}
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");
}
const wrappedFunction = wrapFunction(arg, argSchema);
return [argNames[i], wrappedFunction];
}
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 (peer == null) {
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()?",
);
}
if (args[0] instanceof FluencePeer) {
peer = args[0];
args = args.slice(1);
} else {
peer = Fluence.defaultClient; 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 (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==}