mirror of
https://github.com/fluencelabs/fluence-js.git
synced 2025-06-24 21:31:32 +00:00
Adapt js-client ecosystem to the new API.
This commit is contained in:
@ -21,28 +21,27 @@ import { fileURLToPath } from "url";
|
|||||||
import { compileFromPath } from "@fluencelabs/aqua-api";
|
import { compileFromPath } from "@fluencelabs/aqua-api";
|
||||||
import aquaToJs from "@fluencelabs/aqua-to-js";
|
import aquaToJs from "@fluencelabs/aqua-to-js";
|
||||||
|
|
||||||
const cr = await compileFromPath({
|
const files = ["smoke_test", "finalize_particle"];
|
||||||
filePath: join(
|
|
||||||
dirname(fileURLToPath(import.meta.url)),
|
|
||||||
"_aqua",
|
|
||||||
"smoke_test.aqua",
|
|
||||||
),
|
|
||||||
targetType: "air",
|
|
||||||
imports: [join(dirname(fileURLToPath(import.meta.url)), "node_modules")],
|
|
||||||
});
|
|
||||||
|
|
||||||
const res = await aquaToJs(cr, "ts");
|
for (const file of files) {
|
||||||
|
const cr = await compileFromPath({
|
||||||
|
filePath: join(
|
||||||
|
dirname(fileURLToPath(import.meta.url)),
|
||||||
|
"_aqua",
|
||||||
|
file + ".aqua",
|
||||||
|
),
|
||||||
|
targetType: "air",
|
||||||
|
imports: [fileURLToPath(new URL("./node_modules", import.meta.url))],
|
||||||
|
});
|
||||||
|
|
||||||
if (res == null) {
|
const res = await aquaToJs(cr, "ts");
|
||||||
throw new Error(cr.errors.join("\n"));
|
|
||||||
|
if (res == null) {
|
||||||
|
throw new Error(cr.errors.join("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeFile(
|
||||||
|
fileURLToPath(new URL(join("src", "_aqua", file + ".ts"), import.meta.url)),
|
||||||
|
res.sources,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await writeFile(
|
|
||||||
join(
|
|
||||||
dirname(fileURLToPath(import.meta.url)),
|
|
||||||
"src",
|
|
||||||
"_aqua",
|
|
||||||
"smoke_test.ts",
|
|
||||||
),
|
|
||||||
res.sources,
|
|
||||||
);
|
|
||||||
|
@ -2,71 +2,182 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* This file is auto-generated. Do not edit manually: changes may be erased.
|
* This file is generated using:
|
||||||
* Generated by Aqua compiler: https://github.com/fluencelabs/aqua/.
|
* @fluencelabs/aqua-api version: 0.12.0
|
||||||
* If you find any bugs, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
|
* @fluencelabs/aqua-to-js version: 0.2.0
|
||||||
* Aqua version: 0.12.0
|
* If you find any bugs in generated AIR, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
|
||||||
|
* If you find any bugs in generated JS/TS, please write an issue on GitHub: https://github.com/fluencelabs/js-client/issues
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
import type {
|
import type { IFluenceClient as IFluenceClient$$, ParticleContext as ParticleContext$$ } from '@fluencelabs/js-client';
|
||||||
IFluenceClient as IFluenceClient$$,
|
|
||||||
CallParams as CallParams$$,
|
import {
|
||||||
} from "@fluencelabs/js-client";
|
v5_callFunction as callFunction$$,
|
||||||
import {
|
v5_registerService as registerService$$,
|
||||||
v5_callFunction as callFunction$$,
|
FluencePeer as FluencePeer$$
|
||||||
v5_registerService as registerService$$,
|
} from '@fluencelabs/js-client';
|
||||||
} from "@fluencelabs/js-client";
|
|
||||||
|
/**
|
||||||
|
* @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") {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
throw new Error("Bad schema");
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Services
|
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
export const test_script = `
|
export const test_script = `
|
||||||
(seq
|
(seq
|
||||||
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
(xor
|
(xor
|
||||||
(xor
|
(xor
|
||||||
(call -relay- ("op" "noop") [])
|
(call -relay- ("op" "noop") [])
|
||||||
(fail %last_error%)
|
(fail %last_error%)
|
||||||
)
|
)
|
||||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 0])
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 0])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function test(config?: { ttl?: number }): Promise<void>;
|
|
||||||
|
|
||||||
export function test(
|
export function test(
|
||||||
peer: IFluenceClient$$,
|
config?: {ttl?: number}
|
||||||
config?: { ttl?: number },
|
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
|
|
||||||
export function test(...args: any) {
|
export function test(
|
||||||
return callFunction$$(
|
peer: IFluenceClient$$,
|
||||||
args,
|
config?: {ttl?: number}
|
||||||
{
|
): Promise<void>;
|
||||||
functionName: "test",
|
|
||||||
arrow: {
|
|
||||||
tag: "arrow",
|
|
||||||
domain: {
|
|
||||||
tag: "labeledProduct",
|
|
||||||
fields: {},
|
|
||||||
},
|
|
||||||
codomain: {
|
|
||||||
tag: "nil",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
names: {
|
|
||||||
relay: "-relay-",
|
|
||||||
getDataSrv: "getDataSrv",
|
|
||||||
callbackSrv: "callbackSrv",
|
|
||||||
responseSrv: "callbackSrv",
|
|
||||||
responseFnName: "response",
|
|
||||||
errorHandlingSrv: "errorHandlingSrv",
|
|
||||||
errorFnName: "error",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
test_script,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* eslint-enable */
|
export async function test(...args: any[]) {
|
||||||
|
const argNames = [];
|
||||||
|
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: test_script,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
|
||||||
|
return aqua2ts(result,
|
||||||
|
{
|
||||||
|
"tag": "nil"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -77,7 +77,6 @@ const getRelayTime = () => {
|
|||||||
|
|
||||||
return callAquaFunction({
|
return callAquaFunction({
|
||||||
args,
|
args,
|
||||||
def,
|
|
||||||
script,
|
script,
|
||||||
config,
|
config,
|
||||||
peer: Fluence.defaultClient,
|
peer: Fluence.defaultClient,
|
||||||
|
@ -61,13 +61,6 @@ export const startContentServer = (
|
|||||||
source: "/js-client.min.js",
|
source: "/js-client.min.js",
|
||||||
destination: "/source/index.min.js",
|
destination: "/source/index.min.js",
|
||||||
},
|
},
|
||||||
// TODO:
|
|
||||||
// something like this
|
|
||||||
// {
|
|
||||||
// source: "/@fluencelabs/:name(\\w+)@:version([\\d.]+)/:path*",
|
|
||||||
// destination: "/deps/@fluencelabs/:name/:path",
|
|
||||||
// }
|
|
||||||
// not supported for some reason. Need to manually iterate over all possible paths
|
|
||||||
{
|
{
|
||||||
source: "/@fluencelabs/:name([\\w-]+)@:version([\\d.]+)/dist/:asset",
|
source: "/@fluencelabs/:name([\\w-]+)@:version([\\d.]+)/dist/:asset",
|
||||||
destination: "/node_modules/@fluencelabs/:name/dist/:asset",
|
destination: "/node_modules/@fluencelabs/:name/dist/:asset",
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"ignorePatterns": ["src/**/__snapshots__/**/*"]
|
"ignorePatterns": ["src/**/__snapshots__/**/*", "src/**/*.js"]
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,6 @@
|
|||||||
"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",
|
||||||
@ -24,6 +21,10 @@
|
|||||||
"@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"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@fluencelabs/js-client": "workspace:^"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,16 +122,7 @@ export function typeToTs(t: NonArrowType | ArrowType): string {
|
|||||||
|
|
||||||
// JS-client argument
|
// JS-client argument
|
||||||
if (domain.tag !== "unlabeledProduct") {
|
if (domain.tag !== "unlabeledProduct") {
|
||||||
const generic =
|
args.push(["callParams", `ParticleContext$$`]);
|
||||||
args.length === 0
|
|
||||||
? "null"
|
|
||||||
: args
|
|
||||||
.map(([name]) => {
|
|
||||||
return `'${name}'`;
|
|
||||||
})
|
|
||||||
.join(" | ");
|
|
||||||
|
|
||||||
args.push(["callParams", `CallParams$$<${generic}>`]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const funcArgs = args
|
const funcArgs = args
|
||||||
|
205
packages/core/aqua-to-js/src/generate/__test__/__snapshots__/generate.snap.d.ts
vendored
Normal file
205
packages/core/aqua-to-js/src/generate/__test__/__snapshots__/generate.snap.d.ts
vendored
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is generated using:
|
||||||
|
* @fluencelabs/aqua-api version: 0.0.0
|
||||||
|
* @fluencelabs/aqua-to-js version: 0.0.0
|
||||||
|
* If you find any bugs in generated AIR, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
|
||||||
|
* If you find any bugs in generated JS/TS, please write an issue on GitHub: https://github.com/fluencelabs/js-client/issues
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import type { IFluenceClient as IFluenceClient$$, ParticleContext as ParticleContext$$ } from '@fluencelabs/js-client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
v5_callFunction as callFunction$$,
|
||||||
|
v5_registerService as registerService$$,
|
||||||
|
FluencePeer as FluencePeer$$
|
||||||
|
} from '@fluencelabs/js-client';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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") {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
throw new Error("Bad schema");
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Services
|
||||||
|
export interface SrvDef {
|
||||||
|
create: (wasm_b64_content: string, callParams: ParticleContext$$) => { error: string | null; service_id: string | null; success: boolean; } | Promise<{ error: string | null; service_id: string | null; success: boolean; }>;
|
||||||
|
list: (callParams: ParticleContext$$) => string[] | Promise<string[]>;
|
||||||
|
remove: (service_id: string, callParams: ParticleContext$$) => { error: string | null; success: boolean; } | Promise<{ error: string | null; success: boolean; }>;
|
||||||
|
}
|
||||||
|
export function registerSrv(service: SrvDef): void;
|
||||||
|
export function registerSrv(serviceId: string, service: SrvDef): void;
|
||||||
|
export function registerSrv(peer: IFluenceClient$$, service: SrvDef): void;
|
||||||
|
export function registerSrv(peer: IFluenceClient$$, serviceId: string, service: SrvDef): void;
|
||||||
|
export interface CalcServiceDef {
|
||||||
|
add: (num: number, callParams: ParticleContext$$) => number | Promise<number>;
|
||||||
|
clear_state: (callParams: ParticleContext$$) => void | Promise<void>;
|
||||||
|
divide: (num: number, callParams: ParticleContext$$) => number | Promise<number>;
|
||||||
|
multiply: (num: number, callParams: ParticleContext$$) => number | Promise<number>;
|
||||||
|
state: (callParams: ParticleContext$$) => number | Promise<number>;
|
||||||
|
subtract: (num: number, callParams: ParticleContext$$) => number | Promise<number>;
|
||||||
|
test_logs: (callParams: ParticleContext$$) => void | Promise<void>;
|
||||||
|
}
|
||||||
|
export function registerCalcService(serviceId: string, service: CalcServiceDef): void;
|
||||||
|
export function registerCalcService(peer: IFluenceClient$$, serviceId: string, service: CalcServiceDef): void;
|
||||||
|
export interface HelloWorldDef {
|
||||||
|
hello: (str: string, callParams: ParticleContext$$) => string | Promise<string>;
|
||||||
|
}
|
||||||
|
export function registerHelloWorld(service: HelloWorldDef): void;
|
||||||
|
export function registerHelloWorld(serviceId: string, service: HelloWorldDef): void;
|
||||||
|
export function registerHelloWorld(peer: IFluenceClient$$, service: HelloWorldDef): void;
|
||||||
|
export function registerHelloWorld(peer: IFluenceClient$$, serviceId: string, service: HelloWorldDef): void;
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
export type ResourceTestResult = [string | null, string[]]
|
||||||
|
|
||||||
|
export function resourceTest(
|
||||||
|
label: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<ResourceTestResult>;
|
||||||
|
|
||||||
|
export function resourceTest(
|
||||||
|
peer: IFluenceClient$$,
|
||||||
|
label: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<ResourceTestResult>;
|
||||||
|
|
||||||
|
export function helloTest(
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<string>;
|
||||||
|
|
||||||
|
export function helloTest(
|
||||||
|
peer: IFluenceClient$$,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<string>;
|
||||||
|
|
||||||
|
export function demo_calculation(
|
||||||
|
service_id: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<number>;
|
||||||
|
|
||||||
|
export function demo_calculation(
|
||||||
|
peer: IFluenceClient$$,
|
||||||
|
service_id: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<number>;
|
||||||
|
|
||||||
|
export function marineTest(
|
||||||
|
wasm64: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<number>;
|
||||||
|
|
||||||
|
export function marineTest(
|
||||||
|
peer: IFluenceClient$$,
|
||||||
|
wasm64: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<number>;
|
||||||
|
|
@ -0,0 +1,643 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is generated using:
|
||||||
|
* @fluencelabs/aqua-api version: 0.0.0
|
||||||
|
* @fluencelabs/aqua-to-js version: 0.0.0
|
||||||
|
* If you find any bugs in generated AIR, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
|
||||||
|
* If you find any bugs in generated JS/TS, please write an issue on GitHub: https://github.com/fluencelabs/js-client/issues
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import {
|
||||||
|
v5_callFunction as callFunction$$,
|
||||||
|
v5_registerService as registerService$$,
|
||||||
|
FluencePeer as FluencePeer$$
|
||||||
|
} from '@fluencelabs/js-client';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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") {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
throw new Error("Bad schema");
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Services
|
||||||
|
|
||||||
|
export function registerSrv(...args) {
|
||||||
|
const service = args.pop();
|
||||||
|
const defaultServiceId = "single_module_srv";
|
||||||
|
|
||||||
|
const params = args[0] instanceof FluencePeer$$ ? ({
|
||||||
|
peer: args[0],
|
||||||
|
serviceId: args[1] ?? defaultServiceId
|
||||||
|
}) : ({
|
||||||
|
peer: undefined,
|
||||||
|
serviceId: args[0] ?? defaultServiceId
|
||||||
|
});
|
||||||
|
|
||||||
|
if (params.serviceId == null) {
|
||||||
|
throw new Error("Service ID is not provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
registerService$$({
|
||||||
|
service,
|
||||||
|
...params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function registerCalcService(...args) {
|
||||||
|
const service = args.pop();
|
||||||
|
const defaultServiceId = undefined;
|
||||||
|
|
||||||
|
const params = args[0] instanceof FluencePeer$$ ? ({
|
||||||
|
peer: args[0],
|
||||||
|
serviceId: args[1] ?? defaultServiceId
|
||||||
|
}) : ({
|
||||||
|
peer: undefined,
|
||||||
|
serviceId: args[0] ?? defaultServiceId
|
||||||
|
});
|
||||||
|
|
||||||
|
if (params.serviceId == null) {
|
||||||
|
throw new Error("Service ID is not provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
registerService$$({
|
||||||
|
service,
|
||||||
|
...params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function registerHelloWorld(...args) {
|
||||||
|
const service = args.pop();
|
||||||
|
const defaultServiceId = "hello-world";
|
||||||
|
|
||||||
|
const params = args[0] instanceof FluencePeer$$ ? ({
|
||||||
|
peer: args[0],
|
||||||
|
serviceId: args[1] ?? defaultServiceId
|
||||||
|
}) : ({
|
||||||
|
peer: undefined,
|
||||||
|
serviceId: args[0] ?? defaultServiceId
|
||||||
|
});
|
||||||
|
|
||||||
|
if (params.serviceId == null) {
|
||||||
|
throw new Error("Service ID is not provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
registerService$$({
|
||||||
|
service,
|
||||||
|
...params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
export const resourceTest_script = `
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "label") [] label)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(new $resource_id
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("peer" "timestamp_sec") [] t)
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("registry" "get_key_bytes") [label [] t [] ""] bytes)
|
||||||
|
(xor
|
||||||
|
(call %init_peer_id% ("sig" "sign") [bytes] result)
|
||||||
|
(fail %last_error%)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match result.$.success false
|
||||||
|
(ap result.$.error.[0] $error)
|
||||||
|
)
|
||||||
|
(new $successful
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(ap result.$.signature result_flat)
|
||||||
|
(call -relay- ("registry" "get_key_id") [label %init_peer_id%] id)
|
||||||
|
)
|
||||||
|
(call -relay- ("op" "string_to_b58") [id] k)
|
||||||
|
)
|
||||||
|
(call -relay- ("kad" "neighborhood") [k [] []] nodes)
|
||||||
|
)
|
||||||
|
(par
|
||||||
|
(fold nodes n-0
|
||||||
|
(par
|
||||||
|
(xor
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call n-0 ("peer" "timestamp_sec") [] t-0)
|
||||||
|
(call n-0 ("trust-graph" "get_weight") [%init_peer_id% t-0] weight)
|
||||||
|
)
|
||||||
|
(call n-0 ("registry" "register_key") [label [] t [] "" result_flat.$.[0] weight t-0] result-0)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(match result-0.$.success true
|
||||||
|
(ap true $successful)
|
||||||
|
)
|
||||||
|
(new $-ephemeral-stream-
|
||||||
|
(new #-ephemeral-canon-
|
||||||
|
(canon -relay- $-ephemeral-stream- #-ephemeral-canon-)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(seq
|
||||||
|
(ap result-0.$.error $error)
|
||||||
|
(new $-ephemeral-stream-
|
||||||
|
(new #-ephemeral-canon-
|
||||||
|
(canon -relay- $-ephemeral-stream- #-ephemeral-canon-)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(null)
|
||||||
|
)
|
||||||
|
(fail %last_error%)
|
||||||
|
)
|
||||||
|
(next n-0)
|
||||||
|
)
|
||||||
|
(never)
|
||||||
|
)
|
||||||
|
(null)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(new $status
|
||||||
|
(new $result-1
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(par
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("math" "sub") [1 1] sub)
|
||||||
|
(new $successful_test
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("math" "add") [sub 1] successful_incr)
|
||||||
|
(fold $successful successful_fold_var
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(ap successful_fold_var $successful_test)
|
||||||
|
(canon -relay- $successful_test #successful_iter_canon)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match #successful_iter_canon.length successful_incr
|
||||||
|
(null)
|
||||||
|
)
|
||||||
|
(next successful_fold_var)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(never)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(canon -relay- $successful_test #successful_result_canon)
|
||||||
|
)
|
||||||
|
(ap #successful_result_canon successful_gate)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call -relay- ("math" "sub") [1 1] sub-0)
|
||||||
|
)
|
||||||
|
(ap "ok" $status)
|
||||||
|
)
|
||||||
|
(call -relay- ("peer" "timeout") [6000 "timeout"] $status)
|
||||||
|
)
|
||||||
|
(new $status_test
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("math" "add") [0 1] status_incr)
|
||||||
|
(fold $status status_fold_var
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(ap status_fold_var $status_test)
|
||||||
|
(canon -relay- $status_test #status_iter_canon)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match #status_iter_canon.length status_incr
|
||||||
|
(null)
|
||||||
|
)
|
||||||
|
(next status_fold_var)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(never)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(canon -relay- $status_test #status_result_canon)
|
||||||
|
)
|
||||||
|
(ap #status_result_canon status_gate)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match status_gate.$.[0] "ok"
|
||||||
|
(ap true $result-1)
|
||||||
|
)
|
||||||
|
(ap false $result-1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(new $result-1_test
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("math" "add") [0 1] result-1_incr)
|
||||||
|
(fold $result-1 result-1_fold_var
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(ap result-1_fold_var $result-1_test)
|
||||||
|
(canon -relay- $result-1_test #result-1_iter_canon)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match #result-1_iter_canon.length result-1_incr
|
||||||
|
(null)
|
||||||
|
)
|
||||||
|
(next result-1_fold_var)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(never)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(canon -relay- $result-1_test #result-1_result_canon)
|
||||||
|
)
|
||||||
|
(ap #result-1_result_canon result-1_gate)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match result-1_gate.$.[0] false
|
||||||
|
(ap "resource wasn't created: timeout exceeded" $error)
|
||||||
|
)
|
||||||
|
(ap id $resource_id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(fail %last_error%)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(canon %init_peer_id% $resource_id #-resource_id-fix-0)
|
||||||
|
)
|
||||||
|
(ap #-resource_id-fix-0 -resource_id-flat-0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 0])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(canon %init_peer_id% $error #error_canon)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [-resource_id-flat-0 #error_canon])
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
export async function resourceTest(...args) {
|
||||||
|
const argNames = ["label"];
|
||||||
|
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: resourceTest_script,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
|
||||||
|
return aqua2ts(result,
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": {
|
||||||
|
"name": "string",
|
||||||
|
"tag": "scalar"
|
||||||
|
},
|
||||||
|
"tag": "option"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": {
|
||||||
|
"name": "string",
|
||||||
|
"tag": "scalar"
|
||||||
|
},
|
||||||
|
"tag": "array"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tag": "unlabeledProduct"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const helloTest_script = `
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(xor
|
||||||
|
(call %init_peer_id% ("hello-world" "hello") ["Fluence user"] hello)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 0])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [hello])
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
export async function helloTest(...args) {
|
||||||
|
const argNames = [];
|
||||||
|
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: helloTest_script,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
|
||||||
|
return aqua2ts(result,
|
||||||
|
{
|
||||||
|
"name": "string",
|
||||||
|
"tag": "scalar"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const demo_calculation_script = `
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "service_id") [] service_id)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% (service_id "test_logs") [])
|
||||||
|
(call %init_peer_id% (service_id "add") [10])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (service_id "multiply") [5])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (service_id "subtract") [8])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (service_id "divide") [6])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (service_id "state") [] res)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 0])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [res])
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
export async function demo_calculation(...args) {
|
||||||
|
const argNames = ["service_id"];
|
||||||
|
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: demo_calculation_script,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
|
||||||
|
return aqua2ts(result,
|
||||||
|
{
|
||||||
|
"name": "f64",
|
||||||
|
"tag": "scalar"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const marineTest_script = `
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "wasm64") [] wasm64)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("single_module_srv" "create") [wasm64] serviceResult)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "test_logs") [])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "add") [10])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "multiply") [5])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "subtract") [8])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "divide") [6])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "state") [] res)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 0])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [res])
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
export async function marineTest(...args) {
|
||||||
|
const argNames = ["wasm64"];
|
||||||
|
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: marineTest_script,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
|
||||||
|
return aqua2ts(result,
|
||||||
|
{
|
||||||
|
"name": "f64",
|
||||||
|
"tag": "scalar"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,707 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is generated using:
|
||||||
|
* @fluencelabs/aqua-api version: 0.0.0
|
||||||
|
* @fluencelabs/aqua-to-js version: 0.0.0
|
||||||
|
* If you find any bugs in generated AIR, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
|
||||||
|
* If you find any bugs in generated JS/TS, please write an issue on GitHub: https://github.com/fluencelabs/js-client/issues
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import type { IFluenceClient as IFluenceClient$$, ParticleContext as ParticleContext$$ } from '@fluencelabs/js-client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
v5_callFunction as callFunction$$,
|
||||||
|
v5_registerService as registerService$$,
|
||||||
|
FluencePeer as FluencePeer$$
|
||||||
|
} from '@fluencelabs/js-client';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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") {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
throw new Error("Bad schema");
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Services
|
||||||
|
export interface SrvDef {
|
||||||
|
create: (wasm_b64_content: string, callParams: ParticleContext$$) => { error: string | null; service_id: string | null; success: boolean; } | Promise<{ error: string | null; service_id: string | null; success: boolean; }>;
|
||||||
|
list: (callParams: ParticleContext$$) => string[] | Promise<string[]>;
|
||||||
|
remove: (service_id: string, callParams: ParticleContext$$) => { error: string | null; success: boolean; } | Promise<{ error: string | null; success: boolean; }>;
|
||||||
|
}
|
||||||
|
export function registerSrv(service: SrvDef): void;
|
||||||
|
export function registerSrv(serviceId: string, service: SrvDef): void;
|
||||||
|
export function registerSrv(peer: IFluenceClient$$, service: SrvDef): void;
|
||||||
|
export function registerSrv(peer: IFluenceClient$$, serviceId: string, service: SrvDef): void;
|
||||||
|
export function registerSrv(...args: any[]) {
|
||||||
|
const service = args.pop();
|
||||||
|
const defaultServiceId = "single_module_srv";
|
||||||
|
|
||||||
|
const params = args[0] instanceof FluencePeer$$ ? ({
|
||||||
|
peer: args[0],
|
||||||
|
serviceId: args[1] ?? defaultServiceId
|
||||||
|
}) : ({
|
||||||
|
peer: undefined,
|
||||||
|
serviceId: args[0] ?? defaultServiceId
|
||||||
|
});
|
||||||
|
|
||||||
|
if (params.serviceId == null) {
|
||||||
|
throw new Error("Service ID is not provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
registerService$$({
|
||||||
|
service,
|
||||||
|
...params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CalcServiceDef {
|
||||||
|
add: (num: number, callParams: ParticleContext$$) => number | Promise<number>;
|
||||||
|
clear_state: (callParams: ParticleContext$$) => void | Promise<void>;
|
||||||
|
divide: (num: number, callParams: ParticleContext$$) => number | Promise<number>;
|
||||||
|
multiply: (num: number, callParams: ParticleContext$$) => number | Promise<number>;
|
||||||
|
state: (callParams: ParticleContext$$) => number | Promise<number>;
|
||||||
|
subtract: (num: number, callParams: ParticleContext$$) => number | Promise<number>;
|
||||||
|
test_logs: (callParams: ParticleContext$$) => void | Promise<void>;
|
||||||
|
}
|
||||||
|
export function registerCalcService(serviceId: string, service: CalcServiceDef): void;
|
||||||
|
export function registerCalcService(peer: IFluenceClient$$, serviceId: string, service: CalcServiceDef): void;
|
||||||
|
export function registerCalcService(...args: any[]) {
|
||||||
|
const service = args.pop();
|
||||||
|
const defaultServiceId = undefined;
|
||||||
|
|
||||||
|
const params = args[0] instanceof FluencePeer$$ ? ({
|
||||||
|
peer: args[0],
|
||||||
|
serviceId: args[1] ?? defaultServiceId
|
||||||
|
}) : ({
|
||||||
|
peer: undefined,
|
||||||
|
serviceId: args[0] ?? defaultServiceId
|
||||||
|
});
|
||||||
|
|
||||||
|
if (params.serviceId == null) {
|
||||||
|
throw new Error("Service ID is not provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
registerService$$({
|
||||||
|
service,
|
||||||
|
...params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HelloWorldDef {
|
||||||
|
hello: (str: string, callParams: ParticleContext$$) => string | Promise<string>;
|
||||||
|
}
|
||||||
|
export function registerHelloWorld(service: HelloWorldDef): void;
|
||||||
|
export function registerHelloWorld(serviceId: string, service: HelloWorldDef): void;
|
||||||
|
export function registerHelloWorld(peer: IFluenceClient$$, service: HelloWorldDef): void;
|
||||||
|
export function registerHelloWorld(peer: IFluenceClient$$, serviceId: string, service: HelloWorldDef): void;
|
||||||
|
export function registerHelloWorld(...args: any[]) {
|
||||||
|
const service = args.pop();
|
||||||
|
const defaultServiceId = "hello-world";
|
||||||
|
|
||||||
|
const params = args[0] instanceof FluencePeer$$ ? ({
|
||||||
|
peer: args[0],
|
||||||
|
serviceId: args[1] ?? defaultServiceId
|
||||||
|
}) : ({
|
||||||
|
peer: undefined,
|
||||||
|
serviceId: args[0] ?? defaultServiceId
|
||||||
|
});
|
||||||
|
|
||||||
|
if (params.serviceId == null) {
|
||||||
|
throw new Error("Service ID is not provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
registerService$$({
|
||||||
|
service,
|
||||||
|
...params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
export const resourceTest_script = `
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "label") [] label)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(new $resource_id
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("peer" "timestamp_sec") [] t)
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("registry" "get_key_bytes") [label [] t [] ""] bytes)
|
||||||
|
(xor
|
||||||
|
(call %init_peer_id% ("sig" "sign") [bytes] result)
|
||||||
|
(fail %last_error%)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match result.$.success false
|
||||||
|
(ap result.$.error.[0] $error)
|
||||||
|
)
|
||||||
|
(new $successful
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(ap result.$.signature result_flat)
|
||||||
|
(call -relay- ("registry" "get_key_id") [label %init_peer_id%] id)
|
||||||
|
)
|
||||||
|
(call -relay- ("op" "string_to_b58") [id] k)
|
||||||
|
)
|
||||||
|
(call -relay- ("kad" "neighborhood") [k [] []] nodes)
|
||||||
|
)
|
||||||
|
(par
|
||||||
|
(fold nodes n-0
|
||||||
|
(par
|
||||||
|
(xor
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call n-0 ("peer" "timestamp_sec") [] t-0)
|
||||||
|
(call n-0 ("trust-graph" "get_weight") [%init_peer_id% t-0] weight)
|
||||||
|
)
|
||||||
|
(call n-0 ("registry" "register_key") [label [] t [] "" result_flat.$.[0] weight t-0] result-0)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(match result-0.$.success true
|
||||||
|
(ap true $successful)
|
||||||
|
)
|
||||||
|
(new $-ephemeral-stream-
|
||||||
|
(new #-ephemeral-canon-
|
||||||
|
(canon -relay- $-ephemeral-stream- #-ephemeral-canon-)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(seq
|
||||||
|
(ap result-0.$.error $error)
|
||||||
|
(new $-ephemeral-stream-
|
||||||
|
(new #-ephemeral-canon-
|
||||||
|
(canon -relay- $-ephemeral-stream- #-ephemeral-canon-)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(null)
|
||||||
|
)
|
||||||
|
(fail %last_error%)
|
||||||
|
)
|
||||||
|
(next n-0)
|
||||||
|
)
|
||||||
|
(never)
|
||||||
|
)
|
||||||
|
(null)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(new $status
|
||||||
|
(new $result-1
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(par
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("math" "sub") [1 1] sub)
|
||||||
|
(new $successful_test
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("math" "add") [sub 1] successful_incr)
|
||||||
|
(fold $successful successful_fold_var
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(ap successful_fold_var $successful_test)
|
||||||
|
(canon -relay- $successful_test #successful_iter_canon)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match #successful_iter_canon.length successful_incr
|
||||||
|
(null)
|
||||||
|
)
|
||||||
|
(next successful_fold_var)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(never)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(canon -relay- $successful_test #successful_result_canon)
|
||||||
|
)
|
||||||
|
(ap #successful_result_canon successful_gate)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call -relay- ("math" "sub") [1 1] sub-0)
|
||||||
|
)
|
||||||
|
(ap "ok" $status)
|
||||||
|
)
|
||||||
|
(call -relay- ("peer" "timeout") [6000 "timeout"] $status)
|
||||||
|
)
|
||||||
|
(new $status_test
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("math" "add") [0 1] status_incr)
|
||||||
|
(fold $status status_fold_var
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(ap status_fold_var $status_test)
|
||||||
|
(canon -relay- $status_test #status_iter_canon)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match #status_iter_canon.length status_incr
|
||||||
|
(null)
|
||||||
|
)
|
||||||
|
(next status_fold_var)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(never)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(canon -relay- $status_test #status_result_canon)
|
||||||
|
)
|
||||||
|
(ap #status_result_canon status_gate)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match status_gate.$.[0] "ok"
|
||||||
|
(ap true $result-1)
|
||||||
|
)
|
||||||
|
(ap false $result-1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(new $result-1_test
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("math" "add") [0 1] result-1_incr)
|
||||||
|
(fold $result-1 result-1_fold_var
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(ap result-1_fold_var $result-1_test)
|
||||||
|
(canon -relay- $result-1_test #result-1_iter_canon)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match #result-1_iter_canon.length result-1_incr
|
||||||
|
(null)
|
||||||
|
)
|
||||||
|
(next result-1_fold_var)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(never)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(canon -relay- $result-1_test #result-1_result_canon)
|
||||||
|
)
|
||||||
|
(ap #result-1_result_canon result-1_gate)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(match result-1_gate.$.[0] false
|
||||||
|
(ap "resource wasn't created: timeout exceeded" $error)
|
||||||
|
)
|
||||||
|
(ap id $resource_id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(fail %last_error%)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(canon %init_peer_id% $resource_id #-resource_id-fix-0)
|
||||||
|
)
|
||||||
|
(ap #-resource_id-fix-0 -resource_id-flat-0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 0])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(canon %init_peer_id% $error #error_canon)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [-resource_id-flat-0 #error_canon])
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
|
||||||
|
export type ResourceTestResult = [string | null, string[]]
|
||||||
|
|
||||||
|
export function resourceTest(
|
||||||
|
label: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<ResourceTestResult>;
|
||||||
|
|
||||||
|
export function resourceTest(
|
||||||
|
peer: IFluenceClient$$,
|
||||||
|
label: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<ResourceTestResult>;
|
||||||
|
|
||||||
|
export async function resourceTest(...args: any[]) {
|
||||||
|
const argNames = ["label"];
|
||||||
|
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: resourceTest_script,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
|
||||||
|
return aqua2ts(result,
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": {
|
||||||
|
"name": "string",
|
||||||
|
"tag": "scalar"
|
||||||
|
},
|
||||||
|
"tag": "option"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": {
|
||||||
|
"name": "string",
|
||||||
|
"tag": "scalar"
|
||||||
|
},
|
||||||
|
"tag": "array"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tag": "unlabeledProduct"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const helloTest_script = `
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(xor
|
||||||
|
(call %init_peer_id% ("hello-world" "hello") ["Fluence user"] hello)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 0])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [hello])
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function helloTest(
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<string>;
|
||||||
|
|
||||||
|
export function helloTest(
|
||||||
|
peer: IFluenceClient$$,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<string>;
|
||||||
|
|
||||||
|
export async function helloTest(...args: any[]) {
|
||||||
|
const argNames = [];
|
||||||
|
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: helloTest_script,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
|
||||||
|
return aqua2ts(result,
|
||||||
|
{
|
||||||
|
"name": "string",
|
||||||
|
"tag": "scalar"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const demo_calculation_script = `
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "service_id") [] service_id)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% (service_id "test_logs") [])
|
||||||
|
(call %init_peer_id% (service_id "add") [10])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (service_id "multiply") [5])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (service_id "subtract") [8])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (service_id "divide") [6])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (service_id "state") [] res)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 0])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [res])
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function demo_calculation(
|
||||||
|
service_id: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<number>;
|
||||||
|
|
||||||
|
export function demo_calculation(
|
||||||
|
peer: IFluenceClient$$,
|
||||||
|
service_id: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<number>;
|
||||||
|
|
||||||
|
export async function demo_calculation(...args: any[]) {
|
||||||
|
const argNames = ["service_id"];
|
||||||
|
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: demo_calculation_script,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
|
||||||
|
return aqua2ts(result,
|
||||||
|
{
|
||||||
|
"name": "f64",
|
||||||
|
"tag": "scalar"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const marineTest_script = `
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "wasm64") [] wasm64)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("single_module_srv" "create") [wasm64] serviceResult)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "test_logs") [])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "add") [10])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "multiply") [5])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "subtract") [8])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "divide") [6])
|
||||||
|
)
|
||||||
|
(call %init_peer_id% (serviceResult.$.service_id.[0] "state") [] res)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 0])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [res])
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function marineTest(
|
||||||
|
wasm64: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<number>;
|
||||||
|
|
||||||
|
export function marineTest(
|
||||||
|
peer: IFluenceClient$$,
|
||||||
|
wasm64: string,
|
||||||
|
config?: {ttl?: number}
|
||||||
|
): Promise<number>;
|
||||||
|
|
||||||
|
export async function marineTest(...args: any[]) {
|
||||||
|
const argNames = ["wasm64"];
|
||||||
|
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: marineTest_script,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
|
||||||
|
return aqua2ts(result,
|
||||||
|
{
|
||||||
|
"name": "f64",
|
||||||
|
"tag": "scalar"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -14,46 +14,55 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import url from "url";
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
import { compileFromPath } from "@fluencelabs/aqua-api";
|
import { compileFromPath } from "@fluencelabs/aqua-api";
|
||||||
import { describe, expect, it } from "vitest";
|
import { beforeAll, describe, expect, it } from "vitest";
|
||||||
|
|
||||||
import { getPackageJsonContent, PackageJson } from "../../utils.js";
|
import { getPackageJsonContent, PackageJson } from "../../utils.js";
|
||||||
import { generateTypes, generateSources } from "../index.js";
|
import { generateTypes, generateSources } from "../index.js";
|
||||||
|
import { CompilationResult } from "../interfaces.js";
|
||||||
|
|
||||||
|
let res: Omit<CompilationResult, "funcCall">;
|
||||||
|
let pkg: PackageJson;
|
||||||
|
|
||||||
describe("Aqua to js/ts compiler", () => {
|
describe("Aqua to js/ts compiler", () => {
|
||||||
it("compiles smoke tests successfully", async () => {
|
beforeAll(async () => {
|
||||||
const res = await compileFromPath({
|
res = await compileFromPath({
|
||||||
filePath: url.fileURLToPath(
|
filePath: fileURLToPath(
|
||||||
new URL("./sources/smoke_test.aqua", import.meta.url),
|
new URL("./sources/smoke_test.aqua", import.meta.url),
|
||||||
),
|
),
|
||||||
imports: ["./node_modules"],
|
imports: ["./node_modules"],
|
||||||
targetType: "air",
|
targetType: "air",
|
||||||
});
|
});
|
||||||
|
|
||||||
const pkg: PackageJson = {
|
pkg = {
|
||||||
...(await getPackageJsonContent()),
|
...(await getPackageJsonContent()),
|
||||||
version: "0.0.0",
|
version: "0.0.0",
|
||||||
devDependencies: {
|
devDependencies: {
|
||||||
"@fluencelabs/aqua-api": "0.0.0",
|
"@fluencelabs/aqua-api": "0.0.0",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: see https://github.com/fluencelabs/js-client/pull/366#discussion_r1370567711
|
it("matches js snapshot", async () => {
|
||||||
// @ts-expect-error don't use compileFromPath directly here
|
|
||||||
const jsResult = generateSources(res, "js", pkg);
|
const jsResult = generateSources(res, "js", pkg);
|
||||||
// TODO: see https://github.com/fluencelabs/js-client/pull/366#discussion_r1370567711
|
|
||||||
// @ts-expect-error don't use compileFromPath directly here
|
|
||||||
const jsTypes = generateTypes(res, pkg);
|
const jsTypes = generateTypes(res, pkg);
|
||||||
|
|
||||||
expect(jsResult).toMatchSnapshot();
|
await expect(jsResult).toMatchFileSnapshot(
|
||||||
expect(jsTypes).toMatchSnapshot();
|
"./__snapshots__/generate.snap.js",
|
||||||
|
);
|
||||||
|
|
||||||
// TODO: see https://github.com/fluencelabs/js-client/pull/366#discussion_r1370567711
|
await expect(jsTypes).toMatchFileSnapshot(
|
||||||
// @ts-expect-error don't use compileFromPath directly here
|
"./__snapshots__/generate.snap.d.ts",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("matches ts snapshot", async () => {
|
||||||
const tsResult = generateSources(res, "ts", pkg);
|
const tsResult = generateSources(res, "ts", pkg);
|
||||||
|
|
||||||
expect(tsResult).toMatchSnapshot();
|
await expect(tsResult).toMatchFileSnapshot(
|
||||||
|
"./__snapshots__/generate.snap.ts",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
110
packages/core/aqua-to-js/src/generate/converters.js
Normal file
110
packages/core/aqua-to-js/src/generate/converters.js
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/**
|
||||||
|
* @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") {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
throw new Error("Bad schema");
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
@ -29,23 +29,60 @@ 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 function ${func.funcDef.functionName}(${typeGenerator.type(
|
export async function ${func.funcDef.functionName}(${typeGenerator.type(
|
||||||
"...args",
|
"...args",
|
||||||
"any[]",
|
"any[]",
|
||||||
)}) {
|
)}) {
|
||||||
return callFunction$$(
|
const argNames = [${argNames
|
||||||
args,
|
.map((arg) => {
|
||||||
${JSON.stringify(recursiveRenameLaquaProps(funcDef), null, 4)},
|
return `"${arg}"`;
|
||||||
${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}
|
||||||
|
);
|
||||||
}`;
|
}`;
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { PackageJson } from "../utils.js";
|
import { includeRelative, PackageJson } from "../utils.js";
|
||||||
|
|
||||||
import { OutputType } from "./interfaces.js";
|
import { OutputType } from "./interfaces.js";
|
||||||
|
|
||||||
|
const converters = await includeRelative(import.meta.url, "./converters.js");
|
||||||
|
|
||||||
export default function generateHeader(
|
export default function generateHeader(
|
||||||
{ version, devDependencies }: PackageJson,
|
{ version, devDependencies }: PackageJson,
|
||||||
outputType: OutputType,
|
outputType: OutputType,
|
||||||
@ -35,12 +37,15 @@ export default function generateHeader(
|
|||||||
*/
|
*/
|
||||||
${
|
${
|
||||||
outputType === "ts"
|
outputType === "ts"
|
||||||
? "import type { IFluenceClient as IFluenceClient$$, CallParams as CallParams$$ } from '@fluencelabs/js-client';"
|
? "import type { IFluenceClient as IFluenceClient$$, ParticleContext as ParticleContext$$ } from '@fluencelabs/js-client';"
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
import {
|
import {
|
||||||
v5_callFunction as callFunction$$,
|
v5_callFunction as callFunction$$,
|
||||||
v5_registerService as registerService$$,
|
v5_registerService as registerService$$,
|
||||||
} from '@fluencelabs/js-client';`;
|
FluencePeer as FluencePeer$$
|
||||||
|
} from '@fluencelabs/js-client';
|
||||||
|
|
||||||
|
${converters}`;
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
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 {
|
||||||
@ -42,46 +40,45 @@ 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, srvDef),
|
generateRegisterServiceOverload(typeGenerator, srvName, defaultServiceId),
|
||||||
].join("\n");
|
].join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateRegisterServiceOverload(
|
function generateRegisterServiceOverload(
|
||||||
typeGenerator: TypeGenerator,
|
typeGenerator: TypeGenerator,
|
||||||
srvName: string,
|
srvName: string,
|
||||||
srvDef: ServiceDef,
|
srvDefaultId?: string,
|
||||||
) {
|
) {
|
||||||
return [
|
return `export function register${srvName}(${typeGenerator.type(
|
||||||
`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,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import { readFile } from "fs/promises";
|
import { readFile } from "fs/promises";
|
||||||
import path from "path";
|
import { join } from "path";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ArrowType,
|
ArrowType,
|
||||||
@ -38,7 +39,7 @@ export interface PackageJson {
|
|||||||
|
|
||||||
export async function getPackageJsonContent(): Promise<PackageJson> {
|
export async function getPackageJsonContent(): Promise<PackageJson> {
|
||||||
const content = await readFile(
|
const content = await readFile(
|
||||||
new URL(path.join("..", "package.json"), import.meta.url),
|
new URL(join("..", "package.json"), import.meta.url),
|
||||||
"utf-8",
|
"utf-8",
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -105,3 +106,8 @@ export function recursiveRenameLaquaProps(obj: JSONValue): unknown {
|
|||||||
export function capitalize(str: string) {
|
export function capitalize(str: string) {
|
||||||
return str.slice(0, 1).toUpperCase() + str.slice(1);
|
return str.slice(0, 1).toUpperCase() + str.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function includeRelative(url: string, file: string) {
|
||||||
|
const pathToFile = join(fileURLToPath(url), "..", file);
|
||||||
|
return await readFile(pathToFile, "utf-8");
|
||||||
|
}
|
||||||
|
@ -25,6 +25,11 @@ export type SimpleTypes =
|
|||||||
|
|
||||||
export type NonArrowType = SimpleTypes | ProductType;
|
export type NonArrowType = SimpleTypes | ProductType;
|
||||||
|
|
||||||
|
export type NonArrowSimpleType =
|
||||||
|
| SimpleTypes
|
||||||
|
| UnlabeledProductType
|
||||||
|
| LabeledProductType<SimpleTypes>;
|
||||||
|
|
||||||
export type TopType = {
|
export type TopType = {
|
||||||
/**
|
/**
|
||||||
* Type descriptor. Used for pattern-matching
|
* Type descriptor. Used for pattern-matching
|
||||||
@ -262,34 +267,3 @@ export interface ServiceDef {
|
|||||||
| LabeledProductType<ArrowType<LabeledProductType<SimpleTypes>>>
|
| LabeledProductType<ArrowType<LabeledProductType<SimpleTypes>>>
|
||||||
| NilType;
|
| NilType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Options to configure Aqua function execution
|
|
||||||
*/
|
|
||||||
export interface FnConfig {
|
|
||||||
/**
|
|
||||||
* Sets the TTL (time to live) for particle responsible for the function execution
|
|
||||||
* If the option is not set the default TTL from FluencePeer config is used
|
|
||||||
*/
|
|
||||||
ttl?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getArgumentTypes = (
|
|
||||||
def: FunctionCallDef,
|
|
||||||
): {
|
|
||||||
[key: string]: NonArrowType | ArrowWithoutCallbacks;
|
|
||||||
} => {
|
|
||||||
if (def.arrow.domain.tag !== "labeledProduct") {
|
|
||||||
throw new Error("Should be impossible");
|
|
||||||
}
|
|
||||||
|
|
||||||
return def.arrow.domain.fields;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const isReturnTypeVoid = (def: FunctionCallDef): boolean => {
|
|
||||||
if (def.arrow.codomain.tag === "nil") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return def.arrow.codomain.items.length === 0;
|
|
||||||
};
|
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 { JSONValue } from "../commonTypes.js";
|
|
||||||
|
|
||||||
import {
|
|
||||||
FnConfig,
|
|
||||||
FunctionCallDef,
|
|
||||||
ServiceDef,
|
|
||||||
} from "./aquaTypeDefinitions.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type for callback passed as aqua function argument
|
|
||||||
*/
|
|
||||||
export type ArgCallbackFunction = (
|
|
||||||
...args: JSONValue[]
|
|
||||||
) => JSONValue | Promise<JSONValue>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Arguments passed to Aqua function
|
|
||||||
*/
|
|
||||||
export type PassedArgs = { [key: string]: JSONValue | ArgCallbackFunction };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Arguments for callAquaFunction function
|
|
||||||
*/
|
|
||||||
// TODO: move to js-client side
|
|
||||||
export interface CallAquaFunctionArgs {
|
|
||||||
/**
|
|
||||||
* Peer to call the function on
|
|
||||||
*/
|
|
||||||
peer: unknown;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function definition
|
|
||||||
*/
|
|
||||||
def: FunctionCallDef;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Air script used by the aqua function
|
|
||||||
*/
|
|
||||||
script: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function configuration
|
|
||||||
*/
|
|
||||||
config: FnConfig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Arguments to pass to the function
|
|
||||||
*/
|
|
||||||
args: PassedArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call a function from Aqua script
|
|
||||||
*/
|
|
||||||
export type CallAquaFunctionType = (
|
|
||||||
args: CallAquaFunctionArgs,
|
|
||||||
) => Promise<unknown>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Arguments for registerService function
|
|
||||||
*/
|
|
||||||
export interface RegisterServiceArgs {
|
|
||||||
/**
|
|
||||||
* Peer to register the service on
|
|
||||||
*/
|
|
||||||
peer: unknown;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service definition
|
|
||||||
*/
|
|
||||||
def: ServiceDef;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service id
|
|
||||||
*/
|
|
||||||
serviceId: string | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service implementation
|
|
||||||
*/
|
|
||||||
service: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a service defined in Aqua on a Fluence peer
|
|
||||||
*/
|
|
||||||
export type RegisterServiceType = (args: RegisterServiceArgs) => void;
|
|
@ -15,6 +15,5 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export * from "./compilerSupport/aquaTypeDefinitions.js";
|
export * from "./compilerSupport/aquaTypeDefinitions.js";
|
||||||
export * from "./compilerSupport/compilerSupportInterface.js";
|
|
||||||
export * from "./commonTypes.js";
|
export * from "./commonTypes.js";
|
||||||
export * from "./future.js";
|
export * from "./future.js";
|
||||||
|
@ -14,15 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {
|
import type { CallAquaFunctionArgs } from "./compilerSupport/callFunction.js";
|
||||||
FnConfig,
|
import { ServiceImpl } from "./compilerSupport/types.js";
|
||||||
FunctionCallDef,
|
|
||||||
ServiceDef,
|
|
||||||
PassedArgs,
|
|
||||||
ServiceImpl,
|
|
||||||
} from "@fluencelabs/interfaces";
|
|
||||||
import { getArgumentTypes } from "@fluencelabs/interfaces";
|
|
||||||
|
|
||||||
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";
|
||||||
@ -33,24 +26,37 @@ export const isFluencePeer = (
|
|||||||
return fluencePeerCandidate instanceof 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 corresponding definitions and the air script
|
* The compiler only need to generate a call the function and provide the air script
|
||||||
*
|
|
||||||
* @param rawFnArgs - 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 ({
|
||||||
rawFnArgs: unknown[],
|
config = {},
|
||||||
def: FunctionCallDef,
|
peer,
|
||||||
script: string,
|
args,
|
||||||
): Promise<unknown> => {
|
script,
|
||||||
const { args, client: peer, config } = extractFunctionArgs(rawFnArgs, def);
|
}: CallAquaFunctionArgsTuned): Promise<unknown> => {
|
||||||
|
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()?",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
peer = Fluence.defaultClient;
|
||||||
|
}
|
||||||
|
|
||||||
return callAquaFunction({
|
return callAquaFunction({
|
||||||
args,
|
args,
|
||||||
def,
|
|
||||||
script,
|
script,
|
||||||
config,
|
config,
|
||||||
peer,
|
peer,
|
||||||
@ -59,138 +65,26 @@ export const v5_callFunction = async (
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 air script
|
||||||
* @param args - raw arguments passed by user to the generated function
|
|
||||||
* TODO: dont forget to add jsdoc for new arg
|
|
||||||
* @param def - service definition generated by the Aqua compiler
|
|
||||||
*/
|
*/
|
||||||
export const v5_registerService = (args: unknown[], def: ServiceDef): void => {
|
export const v5_registerService = ({
|
||||||
// TODO: Support this in aqua-to-js package
|
serviceId,
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
service,
|
||||||
const service: ServiceImpl = args.pop() as ServiceImpl;
|
peer,
|
||||||
|
}: RegisterServiceArgs): void => {
|
||||||
|
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()?",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const { peer, serviceId } = extractServiceArgs(args, def.defaultServiceId);
|
peer = Fluence.defaultClient;
|
||||||
|
}
|
||||||
|
|
||||||
registerService({
|
registerService({
|
||||||
def,
|
|
||||||
service,
|
service,
|
||||||
serviceId,
|
serviceId,
|
||||||
peer,
|
peer,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function isConfig(arg: unknown): arg is FnConfig {
|
|
||||||
return typeof arg === "object" && arg !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Arguments could be passed in one these configurations:
|
|
||||||
* [...actualArgs]
|
|
||||||
* [peer, ...actualArgs]
|
|
||||||
* [...actualArgs, config]
|
|
||||||
* [peer, ...actualArgs, config]
|
|
||||||
*
|
|
||||||
* This function select the appropriate configuration and returns
|
|
||||||
* arguments in a structured way of: { peer, config, args }
|
|
||||||
*/
|
|
||||||
function extractFunctionArgs(
|
|
||||||
args: unknown[],
|
|
||||||
def: FunctionCallDef,
|
|
||||||
): {
|
|
||||||
client: FluencePeer;
|
|
||||||
config: FnConfig;
|
|
||||||
args: PassedArgs;
|
|
||||||
} {
|
|
||||||
const argumentTypes = getArgumentTypes(def);
|
|
||||||
const argumentNames = Object.keys(argumentTypes);
|
|
||||||
const numberOfExpectedArgs = argumentNames.length;
|
|
||||||
|
|
||||||
let peer: FluencePeer;
|
|
||||||
let config: FnConfig;
|
|
||||||
|
|
||||||
if (isFluencePeer(args[0])) {
|
|
||||||
peer = args[0];
|
|
||||||
args = args.slice(1);
|
|
||||||
} else {
|
|
||||||
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()?",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
peer = Fluence.defaultClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
const maybeConfig = args[numberOfExpectedArgs];
|
|
||||||
|
|
||||||
if (isConfig(maybeConfig)) {
|
|
||||||
config = maybeConfig;
|
|
||||||
} else {
|
|
||||||
config = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const structuredArgs = args.slice(0, numberOfExpectedArgs);
|
|
||||||
|
|
||||||
if (structuredArgs.length !== numberOfExpectedArgs) {
|
|
||||||
throw new Error(
|
|
||||||
`Incorrect number of arguments. Expecting ${numberOfExpectedArgs}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const argsRes = argumentNames.reduce((acc, name, index) => {
|
|
||||||
return { ...acc, [name]: structuredArgs[index] };
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
return {
|
|
||||||
client: peer,
|
|
||||||
args: argsRes,
|
|
||||||
config: config,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Arguments could be passed in one these configurations:
|
|
||||||
* [serviceObject]
|
|
||||||
* [peer, serviceObject]
|
|
||||||
* [defaultId, serviceObject]
|
|
||||||
* [peer, defaultId, serviceObject]
|
|
||||||
*
|
|
||||||
* Where serviceObject is the raw object with function definitions passed by user
|
|
||||||
*
|
|
||||||
* This function select the appropriate configuration and returns
|
|
||||||
* arguments in a structured way of: { peer, serviceId, service }
|
|
||||||
*/
|
|
||||||
const extractServiceArgs = (
|
|
||||||
args: unknown[],
|
|
||||||
defaultServiceId?: string,
|
|
||||||
): {
|
|
||||||
peer: FluencePeer;
|
|
||||||
serviceId: string | undefined;
|
|
||||||
} => {
|
|
||||||
let peer: FluencePeer;
|
|
||||||
let serviceId: string | undefined;
|
|
||||||
|
|
||||||
if (isFluencePeer(args[0])) {
|
|
||||||
peer = args[0];
|
|
||||||
args = args.slice(1);
|
|
||||||
} else {
|
|
||||||
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()?",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
peer = Fluence.defaultClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof args[0] === "string") {
|
|
||||||
serviceId = args[0];
|
|
||||||
} else {
|
|
||||||
serviceId = defaultServiceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
peer,
|
|
||||||
serviceId,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import { JSONValue } from "@fluencelabs/interfaces";
|
import { JSONValue } from "@fluencelabs/interfaces";
|
||||||
import { it, describe, expect } from "vitest";
|
import { it, describe, expect } from "vitest";
|
||||||
|
|
||||||
import { SendError } from "../../jsPeer/errors.js";
|
import { ExpirationError, SendError } from "../../jsPeer/errors.js";
|
||||||
import { CallServiceData } from "../../jsServiceHost/interfaces.js";
|
import { CallServiceData } from "../../jsServiceHost/interfaces.js";
|
||||||
import { handleTimeout } from "../../particle/Particle.js";
|
import { handleTimeout } from "../../particle/Particle.js";
|
||||||
import { registerHandlersHelper, withClient } from "../../util/testUtils.js";
|
import { registerHandlersHelper, withClient } from "../../util/testUtils.js";
|
||||||
@ -26,6 +26,35 @@ import { checkConnection } from "../checkConnection.js";
|
|||||||
import { nodes, RELAY } from "./connection.js";
|
import { nodes, RELAY } from "./connection.js";
|
||||||
|
|
||||||
describe("FluenceClient usage test suite", () => {
|
describe("FluenceClient usage test suite", () => {
|
||||||
|
it("Should resolve at TTL when fire and forget behavior is used", async () => {
|
||||||
|
await withClient(RELAY, { defaultTtlMs: 600 }, async (peer) => {
|
||||||
|
const script = `
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("load" "relay") [] init_relay)
|
||||||
|
(call init_relay ("peer" "timeout") [60000 "Do you really want to wait for so long?"])
|
||||||
|
)`;
|
||||||
|
|
||||||
|
const particle = await peer.internals.createNewParticle(script);
|
||||||
|
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
const promise = new Promise<JSONValue>((resolve, reject) => {
|
||||||
|
registerHandlersHelper(peer, particle, {
|
||||||
|
load: {
|
||||||
|
relay: () => {
|
||||||
|
return peer.getRelayPeerId();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
peer.internals.initiateParticle(particle, resolve, reject);
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(promise).rejects.toThrow(ExpirationError);
|
||||||
|
expect(Date.now() - 500).toBeGreaterThanOrEqual(now);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("should make a call through network", async () => {
|
it("should make a call through network", async () => {
|
||||||
await withClient(RELAY, {}, async (peer) => {
|
await withClient(RELAY, {}, async (peer) => {
|
||||||
// arrange
|
// arrange
|
||||||
@ -180,7 +209,7 @@ describe("FluenceClient usage test suite", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only("With connection options: defaultTTL", async () => {
|
it("With connection options: defaultTTL", async () => {
|
||||||
await withClient(RELAY, { defaultTtlMs: 1 }, async (peer) => {
|
await withClient(RELAY, { defaultTtlMs: 1 }, async (peer) => {
|
||||||
const isConnected = await checkConnection(peer);
|
const isConnected = await checkConnection(peer);
|
||||||
|
|
||||||
|
@ -14,9 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import assert from "assert";
|
import { JSONValue } from "@fluencelabs/interfaces";
|
||||||
|
|
||||||
import { FnConfig, JSONValue } from "@fluencelabs/interfaces";
|
|
||||||
|
|
||||||
import { FluencePeer } from "../jsPeer/FluencePeer.js";
|
import { FluencePeer } from "../jsPeer/FluencePeer.js";
|
||||||
import { logger } from "../util/logger.js";
|
import { logger } from "../util/logger.js";
|
||||||
@ -46,16 +44,20 @@ const log = logger("aqua");
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type CallAquaFunctionArgs = {
|
export type CallAquaFunctionArgs = {
|
||||||
script: string;
|
script: string;
|
||||||
config: FnConfig;
|
config?: CallAquaFunctionConfig;
|
||||||
peer: FluencePeer;
|
peer: FluencePeer;
|
||||||
args: { [key: string]: JSONValue | ServiceImpl[string] };
|
args: { [key: string]: JSONValue | ServiceImpl[string] };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type CallAquaFunctionConfig = {
|
||||||
|
ttl?: number;
|
||||||
|
};
|
||||||
|
|
||||||
export const callAquaFunction = async ({
|
export const callAquaFunction = async ({
|
||||||
script,
|
script,
|
||||||
config,
|
config = {},
|
||||||
peer,
|
peer,
|
||||||
args,
|
args,
|
||||||
}: CallAquaFunctionArgs) => {
|
}: CallAquaFunctionArgs) => {
|
||||||
@ -69,21 +71,8 @@ export const callAquaFunction = async ({
|
|||||||
let service: ServiceDescription;
|
let service: ServiceDescription;
|
||||||
|
|
||||||
if (typeof argVal === "function") {
|
if (typeof argVal === "function") {
|
||||||
// TODO: Add validation here
|
|
||||||
assert(
|
|
||||||
typeof argVal === "function",
|
|
||||||
"Should not be possible, bad types",
|
|
||||||
);
|
|
||||||
|
|
||||||
service = userHandlerService("callbackSrv", name, argVal);
|
service = userHandlerService("callbackSrv", name, argVal);
|
||||||
} else {
|
} else {
|
||||||
// TODO: Add validation here
|
|
||||||
assert(
|
|
||||||
typeof argVal !== "function",
|
|
||||||
"Should not be possible, bad types",
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log("inject service", name, argVal);
|
|
||||||
service = injectValueService("getDataSrv", name, argVal);
|
service = injectValueService("getDataSrv", name, argVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,6 @@ export const registerService = ({
|
|||||||
serviceId,
|
serviceId,
|
||||||
service,
|
service,
|
||||||
}: RegisterServiceArgs) => {
|
}: RegisterServiceArgs) => {
|
||||||
// TODO: Need to refactor this. We can compute function types from service implementation, making func more type safe
|
|
||||||
log.trace("registering aqua service %o", { serviceId, service });
|
log.trace("registering aqua service %o", { serviceId, service });
|
||||||
|
|
||||||
if (serviceId == null) {
|
if (serviceId == null) {
|
||||||
|
@ -139,8 +139,6 @@ export const userHandlerService = (
|
|||||||
|
|
||||||
const result = await userHandler.bind(null)(...args);
|
const result = await userHandler.bind(null)(...args);
|
||||||
|
|
||||||
console.log(result, "userHandlerService result", serviceId, fnName);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
retCode: ResultCodes.success,
|
retCode: ResultCodes.success,
|
||||||
result: result,
|
result: result,
|
||||||
|
@ -91,7 +91,11 @@ describe.skip("Ephemeral networks tests", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// act
|
// act
|
||||||
client.internals.initiateParticle(particle, () => {});
|
client.internals.initiateParticle(
|
||||||
|
particle,
|
||||||
|
() => {},
|
||||||
|
() => {},
|
||||||
|
);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
await expect(promise).resolves.toBe("success");
|
await expect(promise).resolves.toBe("success");
|
||||||
|
@ -174,10 +174,14 @@ export type {
|
|||||||
KeyPairOptions,
|
KeyPairOptions,
|
||||||
} from "./clientPeer/types.js";
|
} from "./clientPeer/types.js";
|
||||||
|
|
||||||
|
export type { ParticleContext } from "./jsServiceHost/interfaces.js";
|
||||||
|
|
||||||
export { v5_callFunction, v5_registerService } from "./api.js";
|
export { v5_callFunction, v5_registerService } from "./api.js";
|
||||||
|
|
||||||
export { createClient, callAquaFunction, registerService };
|
export { createClient, callAquaFunction, registerService };
|
||||||
|
|
||||||
|
export { ClientPeer } from "./clientPeer/ClientPeer.js";
|
||||||
|
|
||||||
// Deprecated exports. Later they will be exposed only under js-client/keypair path
|
// Deprecated exports. Later they will be exposed only under js-client/keypair path
|
||||||
export {
|
export {
|
||||||
KeyPair,
|
KeyPair,
|
||||||
@ -186,4 +190,8 @@ export {
|
|||||||
fromOpts,
|
fromOpts,
|
||||||
} from "./keypair/index.js";
|
} from "./keypair/index.js";
|
||||||
|
|
||||||
|
export { FluencePeer } from "./jsPeer/FluencePeer.js";
|
||||||
|
|
||||||
|
export type { JSONValue, NonArrowSimpleType } from "@fluencelabs/interfaces";
|
||||||
|
|
||||||
export * from "./network.js";
|
export * from "./network.js";
|
||||||
|
@ -531,8 +531,6 @@ export abstract class FluencePeer {
|
|||||||
item.result.nextPeerPks.toString(),
|
item.result.nextPeerPks.toString(),
|
||||||
);
|
);
|
||||||
|
|
||||||
const interpreterResult = item.result;
|
|
||||||
|
|
||||||
connectionPromise = this.connection
|
connectionPromise = this.connection
|
||||||
.sendParticle(item.result.nextPeerPks, newParticle)
|
.sendParticle(item.result.nextPeerPks, newParticle)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -540,11 +538,6 @@ export abstract class FluencePeer {
|
|||||||
"id %s. send successful",
|
"id %s. send successful",
|
||||||
newParticle.id,
|
newParticle.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (interpreterResult.callRequests.length === 0) {
|
|
||||||
// Nothing to call, just fire-and-forget behavior
|
|
||||||
item.onSuccess(null);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch((e: unknown) => {
|
.catch((e: unknown) => {
|
||||||
log_particle.error(
|
log_particle.error(
|
||||||
@ -622,9 +615,6 @@ export abstract class FluencePeer {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Every air instruction executed or particle will go to relay
|
|
||||||
item.onSuccess(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return connectionPromise;
|
return connectionPromise;
|
||||||
@ -637,7 +627,6 @@ export abstract class FluencePeer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _expireParticle(item: ParticleQueueItem) {
|
private _expireParticle(item: ParticleQueueItem) {
|
||||||
console.log(item);
|
|
||||||
const particleId = item.particle.id;
|
const particleId = item.particle.id;
|
||||||
|
|
||||||
log_particle.debug(
|
log_particle.debug(
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { CallParams } from "@fluencelabs/interfaces";
|
import { ParticleContext } from "../jsServiceHost/interfaces.js";
|
||||||
|
|
||||||
import { TracingDef } from "./_aqua/tracing.js";
|
import { TracingDef } from "./_aqua/tracing.js";
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ export class Tracing implements TracingDef {
|
|||||||
tracingEvent(
|
tracingEvent(
|
||||||
arrowName: string,
|
arrowName: string,
|
||||||
event: string,
|
event: string,
|
||||||
callParams: CallParams<"arrowName" | "event">,
|
callParams: ParticleContext,
|
||||||
): void {
|
): void {
|
||||||
// This console log is intentional
|
// This console log is intentional
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
|
@ -42,7 +42,7 @@ describe("Sig service test suite", () => {
|
|||||||
aqua = functions;
|
aqua = functions;
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only("Use custom sig service, success path", async () => {
|
it("Use custom sig service, success path", async () => {
|
||||||
await withPeer(async (peer) => {
|
await withPeer(async (peer) => {
|
||||||
const customKeyPair = await KeyPair.randomEd25519();
|
const customKeyPair = await KeyPair.randomEd25519();
|
||||||
const customSig = new Sig(customKeyPair);
|
const customSig = new Sig(customKeyPair);
|
||||||
@ -114,7 +114,7 @@ describe("Sig service test suite", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only("Default sig service should be resolvable by peer id", async () => {
|
it("Default sig service should be resolvable by peer id", async () => {
|
||||||
await withPeer(async (peer) => {
|
await withPeer(async (peer) => {
|
||||||
const sig = peer.internals.getServices().sig;
|
const sig = peer.internals.getServices().sig;
|
||||||
|
|
||||||
|
@ -17,10 +17,11 @@
|
|||||||
/**
|
/**
|
||||||
* This compiled aqua file was modified to make it work in monorepo
|
* This compiled aqua file was modified to make it work in monorepo
|
||||||
*/
|
*/
|
||||||
import { CallParams, ServiceImpl } from "@fluencelabs/interfaces";
|
|
||||||
|
|
||||||
import { registerService } from "../../compilerSupport/registerService.js";
|
import { registerService } from "../../compilerSupport/registerService.js";
|
||||||
|
import { ServiceImpl } from "../../compilerSupport/types.js";
|
||||||
import { FluencePeer } from "../../jsPeer/FluencePeer.js";
|
import { FluencePeer } from "../../jsPeer/FluencePeer.js";
|
||||||
|
import { ParticleContext } from "../../jsServiceHost/interfaces.js";
|
||||||
import { Tracing } from "../Tracing.js";
|
import { Tracing } from "../Tracing.js";
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
@ -29,7 +30,7 @@ export interface TracingDef {
|
|||||||
tracingEvent: (
|
tracingEvent: (
|
||||||
arrowName: string,
|
arrowName: string,
|
||||||
event: string,
|
event: string,
|
||||||
callParams: CallParams<"arrowName" | "event">,
|
callParams: ParticleContext,
|
||||||
) => void | Promise<void>;
|
) => void | Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,33 +45,6 @@ export function registerTracing(
|
|||||||
// TODO: fix this after changing registerService signature
|
// TODO: fix this after changing registerService signature
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
service: service as unknown as ServiceImpl,
|
service: service as unknown as ServiceImpl,
|
||||||
def: {
|
|
||||||
defaultServiceId: "tracingSrv",
|
|
||||||
functions: {
|
|
||||||
tag: "labeledProduct",
|
|
||||||
fields: {
|
|
||||||
tracingEvent: {
|
|
||||||
tag: "arrow",
|
|
||||||
domain: {
|
|
||||||
tag: "labeledProduct",
|
|
||||||
fields: {
|
|
||||||
arrowName: {
|
|
||||||
tag: "scalar",
|
|
||||||
name: "string",
|
|
||||||
},
|
|
||||||
event: {
|
|
||||||
tag: "scalar",
|
|
||||||
name: "string",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
codomain: {
|
|
||||||
tag: "nil",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,8 +103,6 @@ export const compileAqua = async (aquaFile: string): Promise<CompiledFile> => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(compilationResult);
|
|
||||||
|
|
||||||
const functions = Object.entries(compilationResult.functions)
|
const functions = Object.entries(compilationResult.functions)
|
||||||
.map(([name, fnInfo]: [string, FunctionInfo]) => {
|
.map(([name, fnInfo]: [string, FunctionInfo]) => {
|
||||||
const callFn = (peer: FluencePeer, args: PassedArgs) => {
|
const callFn = (peer: FluencePeer, args: PassedArgs) => {
|
||||||
|
11
pnpm-lock.yaml
generated
11
pnpm-lock.yaml
generated
@ -162,9 +162,9 @@ importers:
|
|||||||
|
|
||||||
packages/core/aqua-to-js:
|
packages/core/aqua-to-js:
|
||||||
dependencies:
|
dependencies:
|
||||||
ts-pattern:
|
'@fluencelabs/js-client':
|
||||||
specifier: 5.0.5
|
specifier: workspace:^
|
||||||
version: 5.0.5
|
version: link:../js-client
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@fluencelabs/aqua-api':
|
'@fluencelabs/aqua-api':
|
||||||
specifier: 0.12.0
|
specifier: 0.12.0
|
||||||
@ -184,6 +184,9 @@ 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
|
||||||
@ -14063,7 +14066,7 @@ packages:
|
|||||||
|
|
||||||
/ts-pattern@5.0.5:
|
/ts-pattern@5.0.5:
|
||||||
resolution: {integrity: sha512-tL0w8U/pgaacOmkb9fRlYzWEUDCfVjjv9dD4wHTgZ61MjhuMt46VNWTG747NqW6vRzoWIKABVhFSOJ82FvXrfA==}
|
resolution: {integrity: sha512-tL0w8U/pgaacOmkb9fRlYzWEUDCfVjjv9dD4wHTgZ61MjhuMt46VNWTG747NqW6vRzoWIKABVhFSOJ82FvXrfA==}
|
||||||
dev: false
|
dev: true
|
||||||
|
|
||||||
/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==}
|
||||||
|
Reference in New Issue
Block a user