diff --git a/fluence-js-examples/hello-world/aqua/hello-world.aqua b/fluence-js-examples/hello-world/aqua/hello-world.aqua index 7e5e5fe..9dec021 100644 --- a/fluence-js-examples/hello-world/aqua/hello-world.aqua +++ b/fluence-js-examples/hello-world/aqua/hello-world.aqua @@ -2,10 +2,15 @@ import Peer from "@fluencelabs/aqua-lib/builtin.aqua" service HelloWorld("hello-world"): hello(str: string) + getFortune() -> string func sayHello(): HelloWorld.hello("Hello, world!") +func tellFortune() -> string: + res <- HelloWorld.getFortune() + <- res + func getRelayTime() -> u64: on HOST_PEER_ID: ts <- Peer.timestamp_ms() diff --git a/fluence-js-examples/hello-world/package-lock.json b/fluence-js-examples/hello-world/package-lock.json index 6c2078c..eee2605 100644 --- a/fluence-js-examples/hello-world/package-lock.json +++ b/fluence-js-examples/hello-world/package-lock.json @@ -13,7 +13,7 @@ "@fluencelabs/fluence-network-environment": "1.0.10" }, "devDependencies": { - "@fluencelabs/aqua": "^0.3.0-226", + "@fluencelabs/aqua": "^0.3.2-233", "@fluencelabs/aqua-lib": "^0.1.14", "chokidar-cli": "^3.0.0", "ts-node": "^10.2.1", @@ -73,14 +73,16 @@ } }, "node_modules/@fluencelabs/aqua": { - "version": "0.3.0-226", - "resolved": "https://registry.npmjs.org/@fluencelabs/aqua/-/aqua-0.3.0-226.tgz", - "integrity": "sha512-9o0TdgsVNcBvifqo7VqIkN62P9EReE0LUxgWG1rGHi9yxJiGElvEBvrVUzqShffF66Ene7VGEe85lhFIGCfDgg==", + "version": "0.3.2-233", + "resolved": "https://registry.npmjs.org/@fluencelabs/aqua/-/aqua-0.3.2-233.tgz", + "integrity": "sha512-LxwNt/O2ijHA2bG7+qdmnFT//kpIVj7mACBp28LxRpb2kJYMcVDNb9VfyWDiDdoX10PAT96OpkiYvVJPs0mpEw==", "dev": true, + "dependencies": { + "@fluencelabs/fluence": "0.12.1" + }, "bin": { "aqua": "index.js", - "aqua-cli": "error.js", - "aqua-j": "index-java.js" + "aqua-cli": "error.js" } }, "node_modules/@fluencelabs/aqua-lib": { @@ -89,6 +91,30 @@ "integrity": "sha512-H2Q4gIvociUxc4J2mwmH0D+mrU2N2Z+enKCHgBCanMVEE2wZDsZ80GTbDKsQjEq+gpqbnJIk8lJBYW6lyvLJTg==", "dev": true }, + "node_modules/@fluencelabs/aqua/node_modules/@fluencelabs/fluence": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@fluencelabs/fluence/-/fluence-0.12.1.tgz", + "integrity": "sha512-JrMKMHjYILAHQsLLd5H0fLt/UMZv+/PQYxJYe6h9HFyJlZrN1bUV+EcZnUw1u3DZE5k/RXBx0udfmkahggwrqA==", + "dev": true, + "dependencies": { + "@chainsafe/libp2p-noise": "4.0.0", + "@fluencelabs/avm": "0.14.4", + "async": "3.2.0", + "base64-js": "1.5.1", + "bs58": "4.0.1", + "cids": "0.8.1", + "it-length-prefixed": "3.0.1", + "it-pipe": "1.1.0", + "libp2p": "0.32.3", + "libp2p-crypto": "0.19.7", + "libp2p-mplex": "0.10.4", + "libp2p-websockets": "0.16.1", + "loglevel": "1.7.0", + "multiaddr": "10.0.0", + "peer-id": "0.15.3", + "uuid": "8.3.0" + } + }, "node_modules/@fluencelabs/avm": { "version": "0.14.4", "resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.14.4.tgz", @@ -3243,10 +3269,39 @@ } }, "@fluencelabs/aqua": { - "version": "0.3.0-226", - "resolved": "https://registry.npmjs.org/@fluencelabs/aqua/-/aqua-0.3.0-226.tgz", - "integrity": "sha512-9o0TdgsVNcBvifqo7VqIkN62P9EReE0LUxgWG1rGHi9yxJiGElvEBvrVUzqShffF66Ene7VGEe85lhFIGCfDgg==", - "dev": true + "version": "0.3.2-233", + "resolved": "https://registry.npmjs.org/@fluencelabs/aqua/-/aqua-0.3.2-233.tgz", + "integrity": "sha512-LxwNt/O2ijHA2bG7+qdmnFT//kpIVj7mACBp28LxRpb2kJYMcVDNb9VfyWDiDdoX10PAT96OpkiYvVJPs0mpEw==", + "dev": true, + "requires": { + "@fluencelabs/fluence": "0.12.1" + }, + "dependencies": { + "@fluencelabs/fluence": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@fluencelabs/fluence/-/fluence-0.12.1.tgz", + "integrity": "sha512-JrMKMHjYILAHQsLLd5H0fLt/UMZv+/PQYxJYe6h9HFyJlZrN1bUV+EcZnUw1u3DZE5k/RXBx0udfmkahggwrqA==", + "dev": true, + "requires": { + "@chainsafe/libp2p-noise": "4.0.0", + "@fluencelabs/avm": "0.14.4", + "async": "3.2.0", + "base64-js": "1.5.1", + "bs58": "4.0.1", + "cids": "0.8.1", + "it-length-prefixed": "3.0.1", + "it-pipe": "1.1.0", + "libp2p": "0.32.3", + "libp2p-crypto": "0.19.7", + "libp2p-mplex": "0.10.4", + "libp2p-websockets": "0.16.1", + "loglevel": "1.7.0", + "multiaddr": "10.0.0", + "peer-id": "0.15.3", + "uuid": "8.3.0" + } + } + } }, "@fluencelabs/aqua-lib": { "version": "0.1.14", diff --git a/fluence-js-examples/hello-world/package.json b/fluence-js-examples/hello-world/package.json index 4cdc32a..d15ca9b 100644 --- a/fluence-js-examples/hello-world/package.json +++ b/fluence-js-examples/hello-world/package.json @@ -11,7 +11,7 @@ "author": "", "license": "ISC", "devDependencies": { - "@fluencelabs/aqua": "^0.3.0-226", + "@fluencelabs/aqua": "^0.3.2-233", "@fluencelabs/aqua-lib": "^0.1.14", "chokidar-cli": "^3.0.0", "ts-node": "^10.2.1", diff --git a/fluence-js-examples/hello-world/src/_aqua/hello-world.ts b/fluence-js-examples/hello-world/src/_aqua/hello-world.ts index eedb85c..4f83710 100644 --- a/fluence-js-examples/hello-world/src/_aqua/hello-world.ts +++ b/fluence-js-examples/hello-world/src/_aqua/hello-world.ts @@ -1,9 +1,9 @@ /** * * This file is auto-generated. Do not edit manually: changes may be erased. - * Generated by Aqua compiler: https://github.com/fluencelabs/aqua/. + * Generated by Aqua compiler: https://github.com/fluencelabs/aqua/. * If you find any bugs, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues - * Aqua version: 0.3.0-226 + * Aqua version: 0.3.2-233 * */ import { Fluence, FluencePeer } from '@fluencelabs/fluence'; @@ -11,21 +11,27 @@ import { ResultCodes, RequestFlow, RequestFlowBuilder, - CallParams, + CallParams } from '@fluencelabs/fluence/dist/internal/compilerSupport/v1'; +function missingFields(obj: any, fields: string[]): string[] { + return fields.filter(f => !(f in obj)) +} + // Services - export interface HelloWorldDef { - hello: (str: string, callParams: CallParams<'str'>) => void; - } - - export function registerHelloWorld(service: HelloWorldDef): void; +export interface HelloWorldDef { + getFortune: (callParams: CallParams) => string; +hello: (str: string, callParams: CallParams<'str'>) => void; +} +export function registerHelloWorld(service: HelloWorldDef): void; export function registerHelloWorld(serviceId: string, service: HelloWorldDef): void; export function registerHelloWorld(peer: FluencePeer, service: HelloWorldDef): void; export function registerHelloWorld(peer: FluencePeer, serviceId: string, service: HelloWorldDef): void; - export function registerHelloWorld(...args: any) { + + +export function registerHelloWorld(...args: any) { let peer: FluencePeer; let serviceId: any; let service: any; @@ -39,10 +45,9 @@ export function registerHelloWorld(peer: FluencePeer, serviceId: string, service serviceId = args[0]; } else if (typeof args[1] === 'string') { serviceId = args[1]; - } - else { - serviceId = "hello-world" -} + } else { + serviceId = "hello-world" + } // Figuring out which overload is the service. // If the first argument is not Fluence Peer and it is an object, then it can only be the service def @@ -57,157 +62,231 @@ export function registerHelloWorld(peer: FluencePeer, serviceId: string, service service = args[2]; } - peer.internals.callServiceHandler.use((req, resp, next) => { - if (req.serviceId !== serviceId) { - next(); - return; - } - - - if (req.fnName === 'hello') { - - const callParams = { - ...req.particleContext, - tetraplets: { - str: req.tetraplets[0] - }, - }; - resp.retCode = ResultCodes.success; - service.hello(req.args[0], callParams); resp.result = {} + const incorrectServiceDefinitions = missingFields(service, ['getFortune', 'hello']); + if (!!incorrectServiceDefinitions.length) { + throw new Error("Error registering service HelloWorld: missing functions: " + incorrectServiceDefinitions.map((d) => "'" + d + "'").join(", ")) + } - } - - - next(); - }); - } - - -// Functions - - export function sayHello(config?: {ttl?: number}) : Promise; - export function sayHello(peer: FluencePeer, config?: {ttl?: number}) : Promise; - export function sayHello(...args: any) { - let peer: FluencePeer; - - let config: any; - if (FluencePeer.isInstance(args[0])) { - peer = args[0]; - config = args[1]; - } else { - peer = Fluence.getPeer(); - config = args[0]; - } - - let request: RequestFlow; - const promise = new Promise((resolve, reject) => { - const r = new RequestFlowBuilder() - .disableInjections() - .withRawScript( - ` - (xor - (seq - (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) - (call %init_peer_id% ("hello-world" "hello") ["Hello, world!"]) - ) - (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) -) - - `, - ) - .configHandler((h) => { - h.on('getDataSrv', '-relay-', () => { - return peer.getStatus().relayPeerId; - }); - - h.onEvent('callbackSrv', 'response', (args) => { - -}); - - h.onEvent('errorHandlingSrv', 'error', (args) => { - const [err] = args; - reject(err); - }); - }) - .handleScriptError(reject) - .handleTimeout(() => { - reject('Request timed out for sayHello'); - }) - if(config && config.ttl) { - r.withTTL(config.ttl) + peer.internals.callServiceHandler.use((req, resp, next) => { + if (req.serviceId !== serviceId) { + next(); + return; } - request = r.build(); + + if (req.fnName === 'getFortune') { + const callParams = { + ...req.particleContext, + tetraplets: { + + }, + }; + resp.retCode = ResultCodes.success; + resp.result = service.getFortune(callParams) + } + +if (req.fnName === 'hello') { + const callParams = { + ...req.particleContext, + tetraplets: { + str: req.tetraplets[0] + }, + }; + resp.retCode = ResultCodes.success; + service.hello(req.args[0], callParams); resp.result = {} + } + + next(); + }); +} + +// Functions + + +export function sayHello(config?: {ttl?: number}): Promise; +export function sayHello(peer: FluencePeer, config?: {ttl?: number}): Promise; +export function sayHello(...args: any) { + let peer: FluencePeer; + + let config: any; + if (FluencePeer.isInstance(args[0])) { + peer = args[0]; + config = args[1]; + } else { + peer = Fluence.getPeer(); + config = args[0]; + } + + let request: RequestFlow; + const promise = new Promise((resolve, reject) => { + const r = new RequestFlowBuilder() + .disableInjections() + .withRawScript(` + (xor + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("hello-world" "hello") ["Hello, world!"]) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + `, + ) + .configHandler((h) => { + h.on('getDataSrv', '-relay-', () => { + return peer.getStatus().relayPeerId; + }); + + h.onEvent('callbackSrv', 'response', (args) => { + + }); + h.onEvent('errorHandlingSrv', 'error', (args) => { + const [err] = args; + reject(err); + }); + }) + .handleScriptError(reject) + .handleTimeout(() => { + reject('Request timed out for sayHello'); + }) + + if (config && config.ttl) { + r.withTTL(config.ttl) + } + + request = r.build(); }); peer.internals.initiateFlow(request!); return Promise.race([promise, Promise.resolve()]); } - + - export function getRelayTime(config?: {ttl?: number}) : Promise; - export function getRelayTime(peer: FluencePeer, config?: {ttl?: number}) : Promise; - export function getRelayTime(...args: any) { - let peer: FluencePeer; - - let config: any; - if (FluencePeer.isInstance(args[0])) { - peer = args[0]; - config = args[1]; - } else { - peer = Fluence.getPeer(); - config = args[0]; - } - - let request: RequestFlow; - const promise = new Promise((resolve, reject) => { - const r = new RequestFlowBuilder() - .disableInjections() - .withRawScript( - ` - (xor - (seq - (seq - (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) - (xor - (call -relay- ("peer" "timestamp_ms") [] ts) - (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) - ) - ) - (xor - (call %init_peer_id% ("callbackSrv" "response") [ts]) - (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) - ) - ) - (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) -) +export function tellFortune(config?: {ttl?: number}): Promise; +export function tellFortune(peer: FluencePeer, config?: {ttl?: number}): Promise; +export function tellFortune(...args: any) { + let peer: FluencePeer; - `, - ) - .configHandler((h) => { - h.on('getDataSrv', '-relay-', () => { - return peer.getStatus().relayPeerId; - }); - - h.onEvent('callbackSrv', 'response', (args) => { - const [res] = args; - resolve(res); -}); + let config: any; + if (FluencePeer.isInstance(args[0])) { + peer = args[0]; + config = args[1]; + } else { + peer = Fluence.getPeer(); + config = args[0]; + } - h.onEvent('errorHandlingSrv', 'error', (args) => { - const [err] = args; - reject(err); - }); - }) - .handleScriptError(reject) - .handleTimeout(() => { - reject('Request timed out for getRelayTime'); - }) - if(config && config.ttl) { - r.withTTL(config.ttl) - } - request = r.build(); + let request: RequestFlow; + const promise = new Promise((resolve, reject) => { + const r = new RequestFlowBuilder() + .disableInjections() + .withRawScript(` + (xor + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("hello-world" "getFortune") [] res) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [res]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + `, + ) + .configHandler((h) => { + h.on('getDataSrv', '-relay-', () => { + return peer.getStatus().relayPeerId; + }); + + h.onEvent('callbackSrv', 'response', (args) => { + const [res] = args; + resolve(res); + }); + h.onEvent('errorHandlingSrv', 'error', (args) => { + const [err] = args; + reject(err); + }); + }) + .handleScriptError(reject) + .handleTimeout(() => { + reject('Request timed out for tellFortune'); + }) + + if (config && config.ttl) { + r.withTTL(config.ttl) + } + + request = r.build(); + }); + peer.internals.initiateFlow(request!); + return promise; +} + + + +export function getRelayTime(config?: {ttl?: number}): Promise; +export function getRelayTime(peer: FluencePeer, config?: {ttl?: number}): Promise; +export function getRelayTime(...args: any) { + let peer: FluencePeer; + + let config: any; + if (FluencePeer.isInstance(args[0])) { + peer = args[0]; + config = args[1]; + } else { + peer = Fluence.getPeer(); + config = args[0]; + } + + let request: RequestFlow; + const promise = new Promise((resolve, reject) => { + const r = new RequestFlowBuilder() + .disableInjections() + .withRawScript(` + (xor + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (xor + (call -relay- ("peer" "timestamp_ms") [] ts) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [ts]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) + ) + `, + ) + .configHandler((h) => { + h.on('getDataSrv', '-relay-', () => { + return peer.getStatus().relayPeerId; + }); + + h.onEvent('callbackSrv', 'response', (args) => { + const [res] = args; + resolve(res); + }); + h.onEvent('errorHandlingSrv', 'error', (args) => { + const [err] = args; + reject(err); + }); + }) + .handleScriptError(reject) + .handleTimeout(() => { + reject('Request timed out for getRelayTime'); + }) + + if (config && config.ttl) { + r.withTTL(config.ttl) + } + + request = r.build(); }); peer.internals.initiateFlow(request!); return promise; } - diff --git a/fluence-js-examples/hello-world/src/index.ts b/fluence-js-examples/hello-world/src/index.ts index db21cce..b0172fd 100644 --- a/fluence-js-examples/hello-world/src/index.ts +++ b/fluence-js-examples/hello-world/src/index.ts @@ -4,19 +4,27 @@ import { registerHelloWorld, sayHello, getRelayTime, + tellFortune, } from "./_aqua/hello-world"; async function main() { await Fluence.start({ connectTo: krasnodar[0] }); registerHelloWorld({ - hello: async (str) => { + hello: (str) => { console.log(str); }, + getFortune: async () => { + await new Promise(resolve => { + setTimeout(resolve, 1000) + }) + return "Wealth awaits you very soon." }); await sayHello(); + console.log(await tellFortune()); + const relayTime = await getRelayTime(); console.log("The relay time is: ", new Date(relayTime).toLocaleString());