This commit is contained in:
Akim Mamedov 2023-11-16 21:16:03 +07:00
parent 26bfc36985
commit ec830bca76
17 changed files with 86 additions and 115 deletions

View File

@ -23,6 +23,8 @@
"@fluencelabs/interfaces": "workspace:*", "@fluencelabs/interfaces": "workspace:*",
"@fluencelabs/js-client": "workspace:^", "@fluencelabs/js-client": "workspace:^",
"@fluencelabs/registry": "0.8.7", "@fluencelabs/registry": "0.8.7",
"@fluencelabs/spell": "0.5.20",
"@fluencelabs/trust-graph": "0.4.7",
"vitest": "0.34.6", "vitest": "0.34.6",
"zod": "3.22.4" "zod": "3.22.4"
} }

View File

@ -11,6 +11,7 @@
*/ */
import type { IFluenceClient as IFluenceClient$$, ParticleContext as ParticleContext$$ } from '@fluencelabs/js-client'; import type { IFluenceClient as IFluenceClient$$, ParticleContext as ParticleContext$$ } from '@fluencelabs/js-client';
// Making aliases to reduce chance of accidental name collision
import { import {
v5_callFunction as callFunction$$, v5_callFunction as callFunction$$,
v5_registerService as registerService$$, v5_registerService as registerService$$,
@ -47,47 +48,21 @@ export function registerHelloWorld(peer: IFluenceClient$$, service: HelloWorldDe
export function registerHelloWorld(peer: IFluenceClient$$, serviceId: string, service: HelloWorldDef): void; export function registerHelloWorld(peer: IFluenceClient$$, serviceId: string, service: HelloWorldDef): void;
// Functions // Functions
export type ResourceTestResult = [string | null, string[]] export type ResourceTestResultType = [string | null, string[]]
export function resourceTest( export type resourceTestParams = [label: string, config?: {ttl?: number}] | [peer: IFluenceClient$$, label: string, config?: {ttl?: number}];
label: string,
config?: {ttl?: number}
): Promise<ResourceTestResult>;
export function resourceTest( export type ResourceTestResult = Promise<ResourceTestResultType>;
peer: IFluenceClient$$,
label: string,
config?: {ttl?: number}
): Promise<ResourceTestResult>;
export function helloTest( export type helloTestParams = [config?: {ttl?: number}] | [peer: IFluenceClient$$, config?: {ttl?: number}];
config?: {ttl?: number}
): Promise<string>;
export function helloTest( export type HelloTestResult = Promise<string>;
peer: IFluenceClient$$,
config?: {ttl?: number}
): Promise<string>;
export function demo_calculation( export type demo_calculationParams = [service_id: string, config?: {ttl?: number}] | [peer: IFluenceClient$$, service_id: string, config?: {ttl?: number}];
service_id: string,
config?: {ttl?: number}
): Promise<number>;
export function demo_calculation( export type Demo_calculationResult = Promise<number>;
peer: IFluenceClient$$,
service_id: string,
config?: {ttl?: number}
): Promise<number>;
export function marineTest( export type marineTestParams = [wasm64: string, config?: {ttl?: number}] | [peer: IFluenceClient$$, wasm64: string, config?: {ttl?: number}];
wasm64: string,
config?: {ttl?: number}
): Promise<number>;
export function marineTest( export type MarineTestResult = Promise<number>;
peer: IFluenceClient$$,
wasm64: string,
config?: {ttl?: number}
): Promise<number>;

View File

@ -11,6 +11,7 @@
*/ */
// Making aliases to reduce chance of accidental name collision
import { import {
v5_callFunction as callFunction$$, v5_callFunction as callFunction$$,
v5_registerService as registerService$$, v5_registerService as registerService$$,

View File

@ -11,6 +11,7 @@
*/ */
import type { IFluenceClient as IFluenceClient$$, ParticleContext as ParticleContext$$ } from '@fluencelabs/js-client'; import type { IFluenceClient as IFluenceClient$$, ParticleContext as ParticleContext$$ } from '@fluencelabs/js-client';
// Making aliases to reduce chance of accidental name collision
import { import {
v5_callFunction as callFunction$$, v5_callFunction as callFunction$$,
v5_registerService as registerService$$, v5_registerService as registerService$$,
@ -539,20 +540,13 @@ export const resourceTest_script = `
) )
`; `;
export type ResourceTestResult = [string | null, string[]] export type ResourceTestResultType = [string | null, string[]]
export function resourceTest( export type resourceTestParams = [label: string, config?: {ttl?: number}] | [peer: IFluenceClient$$, label: string, config?: {ttl?: number}];
label: string,
config?: {ttl?: number}
): Promise<ResourceTestResult>;
export function resourceTest( export type ResourceTestResult = Promise<ResourceTestResultType>;
peer: IFluenceClient$$,
label: string,
config?: {ttl?: number}
): Promise<ResourceTestResult>;
export function resourceTest(...args: any[]) { export function resourceTest(...args: resourceTestParams): ResourceTestResult {
return callFunction$$( return callFunction$$(
args, args,
{ {
@ -615,16 +609,11 @@ export const helloTest_script = `
) )
`; `;
export function helloTest( export type helloTestParams = [config?: {ttl?: number}] | [peer: IFluenceClient$$, config?: {ttl?: number}];
config?: {ttl?: number}
): Promise<string>;
export function helloTest( export type HelloTestResult = Promise<string>;
peer: IFluenceClient$$,
config?: {ttl?: number}
): Promise<string>;
export function helloTest(...args: any[]) { export function helloTest(...args: helloTestParams): HelloTestResult {
return callFunction$$( return callFunction$$(
args, args,
{ {
@ -690,18 +679,11 @@ export const demo_calculation_script = `
) )
`; `;
export function demo_calculation( export type demo_calculationParams = [service_id: string, config?: {ttl?: number}] | [peer: IFluenceClient$$, service_id: string, config?: {ttl?: number}];
service_id: string,
config?: {ttl?: number}
): Promise<number>;
export function demo_calculation( export type Demo_calculationResult = Promise<number>;
peer: IFluenceClient$$,
service_id: string,
config?: {ttl?: number}
): Promise<number>;
export function demo_calculation(...args: any[]) { export function demo_calculation(...args: demo_calculationParams): Demo_calculationResult {
return callFunction$$( return callFunction$$(
args, args,
{ {
@ -775,18 +757,11 @@ export const marineTest_script = `
) )
`; `;
export function marineTest( export type marineTestParams = [wasm64: string, config?: {ttl?: number}] | [peer: IFluenceClient$$, wasm64: string, config?: {ttl?: number}];
wasm64: string,
config?: {ttl?: number}
): Promise<number>;
export function marineTest( export type MarineTestResult = Promise<number>;
peer: IFluenceClient$$,
wasm64: string,
config?: {ttl?: number}
): Promise<number>;
export function marineTest(...args: any[]) { export function marineTest(...args: marineTestParams): MarineTestResult {
return callFunction$$( return callFunction$$(
args, args,
{ {

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { recursiveRenameLaquaProps } from "../utils.js"; import { capitalize, recursiveRenameLaquaProps } from "../utils.js";
import { AquaFunction, TypeGenerator } from "./interfaces.js"; import { AquaFunction, TypeGenerator } from "./interfaces.js";
@ -40,8 +40,11 @@ ${func.script}\`;
${typeGenerator.funcType(func)} ${typeGenerator.funcType(func)}
export function ${func.funcDef.functionName}(${typeGenerator.type( export function ${func.funcDef.functionName}(${typeGenerator.type(
"...args", "...args",
"any[]", `${func.funcDef.functionName}Params`,
)}) { )})${typeGenerator.type(
"",
`${capitalize(func.funcDef.functionName)}Result`,
)} {
return callFunction$$( return callFunction$$(
args, args,
${JSON.stringify(recursiveRenameLaquaProps(funcDef), null, 4)}, ${JSON.stringify(recursiveRenameLaquaProps(funcDef), null, 4)},

View File

@ -56,7 +56,7 @@ export class TSTypeGenerator implements TypeGenerator {
args.push([undefined, `config?: {ttl?: number}`]); args.push([undefined, `config?: {ttl?: number}`]);
const argsDefs = args.map(([, def]) => { const argsDefs = args.map(([, def]) => {
return " " + def; return def;
}); });
const argsDesc = args const argsDesc = args
@ -68,28 +68,28 @@ export class TSTypeGenerator implements TypeGenerator {
}); });
const functionOverloads = [ const functionOverloads = [
argsDefs.join(",\n"), argsDefs.join(", "),
[` peer: ${CLIENT}`, ...argsDefs].join(",\n"), [`peer: ${CLIENT}`, ...argsDefs].join(", "),
]; ];
const [resTypeDesc, resType] = genTypeName( const [resTypeDesc, resType] = genTypeName(
funcDef.arrow.codomain, funcDef.arrow.codomain,
capitalize(funcDef.functionName) + "Result", capitalize(funcDef.functionName) + "ResultType",
); );
const functionOverloadArgsType = functionOverloads
.map((overload) => {
return `[${overload}]`;
})
.join(" | ");
return [ return [
argsDesc.join("\n"), argsDesc.join("\n"),
resTypeDesc ?? "", resTypeDesc ?? "",
functionOverloads `export type ${funcDef.functionName}Params = ${functionOverloadArgsType};`,
.flatMap((fo) => { `export type ${capitalize(
return [ funcDef.functionName,
`export function ${funcDef.functionName}(`, )}Result = Promise<${resType}>;\n`,
fo,
`): Promise<${resType}>;`,
"",
];
})
.join("\n"),
] ]
.filter((s) => { .filter((s) => {
return s !== ""; return s !== "";

View File

@ -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 { ExpirationError, SendError } from "../../jsPeer/errors.js"; import { ExpirationError } 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";

View File

@ -82,6 +82,9 @@ export const callAquaFunction = async ({
registerParticleScopeService(peer, particle, service); registerParticleScopeService(peer, particle, service);
} }
// If fireAndForget is enabled, then function call completed when one of the two conditions is met:
// 1. The particle is sent to the network
// 2. All CallRequests are executed, e.g., all variable loading and local function calls are completed
if (!fireAndForget) { if (!fireAndForget) {
registerParticleScopeService(peer, particle, responseService(resolve)); registerParticleScopeService(peer, particle, responseService(resolve));
} }
@ -89,9 +92,6 @@ export const callAquaFunction = async ({
registerParticleScopeService(peer, particle, injectRelayService(peer)); registerParticleScopeService(peer, particle, injectRelayService(peer));
registerParticleScopeService(peer, particle, errorHandlingService(reject)); registerParticleScopeService(peer, particle, errorHandlingService(reject));
// If function is void, then it's completed when one of the two conditions is met:
// 1. The particle is sent to the network (state 'sent')
// 2. All CallRequests are executed, e.g., all variable loading and local function calls are completed (state 'localWorkDone')
peer.internals.initiateParticle(particle, resolve, reject); peer.internals.initiateParticle(particle, resolve, reject);
}); });

View File

@ -28,7 +28,9 @@ interface RegisterServiceArgs {
service: ServiceImpl; service: ServiceImpl;
} }
const findAllPossibleServiceMethods = (service: ServiceImpl): Set<string> => { const findAllPossibleRegisteredServiceFunctions = (
service: ServiceImpl,
): Set<string> => {
let prototype: Record<string, unknown> = service; let prototype: Record<string, unknown> = service;
const serviceMethods = new Set<string>(); const serviceMethods = new Set<string>();
@ -60,17 +62,17 @@ export const registerService = ({
throw new Error("Service ID must be specified"); throw new Error("Service ID must be specified");
} }
const serviceMethods = findAllPossibleServiceMethods(service); const serviceFunctions = findAllPossibleRegisteredServiceFunctions(service);
for (const method of serviceMethods) { for (const serviceFunction of serviceFunctions) {
// The function has type of (arg1, arg2, arg3, ... , ParticleContext) => CallServiceResultType | void // The function has type of (arg1, arg2, arg3, ... , ParticleContext) => CallServiceResultType | void
// Account for the fact that user service might be defined as a class - .bind(...) // Account for the fact that user service might be defined as a class - .bind(...)
const handler = service[method]; const handler = service[serviceFunction];
const userDefinedHandler = handler.bind(service); const userDefinedHandler = handler.bind(service);
const serviceDescription = userHandlerService( const serviceDescription = userHandlerService(
serviceId, serviceId,
method, serviceFunction,
userDefinedHandler, userDefinedHandler,
); );

View File

@ -334,6 +334,7 @@ export abstract class FluencePeer {
registerTracing(this, "tracingSrv", this._classServices.tracing); registerTracing(this, "tracingSrv", this._classServices.tracing);
} }
// TODO: too long, refactor
private _startParticleProcessing() { private _startParticleProcessing() {
this._particleSourceSubscription = this.connection.particleSource.subscribe( this._particleSourceSubscription = this.connection.particleSource.subscribe(
{ {

View File

@ -41,7 +41,6 @@ export class NodeUtils {
} }
try { try {
// Strange enough, but Buffer type works here, while reading with encoding 'utf-8' doesn't
const data = await readFile(path, "base64"); const data = await readFile(path, "base64");
return { return {

View File

@ -45,7 +45,7 @@ export class Srv {
if (!this.securityGuard_create(callParams)) { if (!this.securityGuard_create(callParams)) {
return { return {
success: false, success: false,
error: ["Security guard validation failed"], error: ["Marine services could be registered on %init_peer_id% only"],
service_id: null, service_id: null,
}; };
} }
@ -80,7 +80,7 @@ export class Srv {
if (!this.securityGuard_remove(callParams)) { if (!this.securityGuard_remove(callParams)) {
return { return {
success: false, success: false,
error: ["Security guard validation failed"], error: ["Marine services could be remove on %init_peer_id% only"],
service_id: null, service_id: null,
}; };
} }

View File

@ -23,11 +23,11 @@ export function registerNodeUtils(
serviceId: string, serviceId: string,
service: NodeUtils, service: NodeUtils,
) { ) {
const anyService: Record<never, unknown> = service; const nodeUtilsService: Record<never, unknown> = service;
registerService({ registerService({
peer, peer,
service: anyService, service: nodeUtilsService,
serviceId, serviceId,
}); });
} }

View File

@ -45,11 +45,11 @@ export function registerSig(
serviceId: string, serviceId: string,
service: Sig, service: Sig,
) { ) {
const anyService: Record<never, unknown> = service; const sigService: Record<never, unknown> = service;
registerService({ registerService({
peer, peer,
service: anyService, service: sigService,
serviceId, serviceId,
}); });
} }

View File

@ -23,12 +23,12 @@ export function registerSrv(
serviceId: string, serviceId: string,
service: Srv, service: Srv,
) { ) {
const anyService: Record<never, unknown> = service; const singleModuleService: Record<never, unknown> = service;
registerService({ registerService({
peer, peer,
serviceId, serviceId,
service: anyService, service: singleModuleService,
}); });
} }

View File

@ -19,7 +19,6 @@
*/ */
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 { ParticleContext } from "../../jsServiceHost/interfaces.js";
import { Tracing } from "../Tracing.js"; import { Tracing } from "../Tracing.js";
@ -39,13 +38,11 @@ export function registerTracing(
serviceId: string, serviceId: string,
service: Tracing, service: Tracing,
) { ) {
const tracingService: Record<never, unknown> = service;
registerService({ registerService({
peer, peer,
serviceId, serviceId,
// TODO: fix this after changing registerService signature service: tracingService,
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
service: service as unknown as ServiceImpl,
}); });
} }
// Functions

16
pnpm-lock.yaml generated
View File

@ -181,6 +181,12 @@ importers:
'@fluencelabs/registry': '@fluencelabs/registry':
specifier: 0.8.7 specifier: 0.8.7
version: 0.8.7 version: 0.8.7
'@fluencelabs/spell':
specifier: 0.5.20
version: 0.5.20
'@fluencelabs/trust-graph':
specifier: 0.4.7
version: 0.4.7
vitest: vitest:
specifier: 0.34.6 specifier: 0.34.6
version: 0.34.6 version: 0.34.6
@ -3725,6 +3731,10 @@ packages:
'@fluencelabs/trust-graph': 0.4.1 '@fluencelabs/trust-graph': 0.4.1
dev: true dev: true
/@fluencelabs/spell@0.5.20:
resolution: {integrity: sha512-QFbknWwALLUWMzpWkFt34McuwTz9xwQuiPP1zXqhPqVZ1J6g8F3gwHHtzgHFW5Z7WrRmwsL+IQtFJy8YZubhDw==}
dev: true
/@fluencelabs/threads@2.0.0: /@fluencelabs/threads@2.0.0:
resolution: {integrity: sha512-dgYpZg55OcEmop1U3G2bFKEJXg2avjXWYfWsdPlkSbHOHguaRifvr5bgwIYTg1wxoPGcn0jegcjKKwrY0qrV+g==} resolution: {integrity: sha512-dgYpZg55OcEmop1U3G2bFKEJXg2avjXWYfWsdPlkSbHOHguaRifvr5bgwIYTg1wxoPGcn0jegcjKKwrY0qrV+g==}
dependencies: dependencies:
@ -3744,6 +3754,12 @@ packages:
'@fluencelabs/aqua-lib': 0.7.3 '@fluencelabs/aqua-lib': 0.7.3
dev: true dev: true
/@fluencelabs/trust-graph@0.4.7:
resolution: {integrity: sha512-e4TxWimUh9GBWjqSO8WGsSqjZfyIs6f39/8Pzfo6PCcNoSf8FPaaO817Pw4FmAXYEKR1IalIUX3CDdym3NlHWw==}
dependencies:
'@fluencelabs/aqua-lib': 0.7.3
dev: true
/@fluencelabs/trust-graph@3.1.2: /@fluencelabs/trust-graph@3.1.2:
resolution: {integrity: sha512-HpyHtiomh09wv6/83z+bhbkqVngIUdqNGEXRTIPg4sArVPMZ9UCXBrkQsHDRqdMUx0lBAcgB3IjlbdhkwHGaXA==} resolution: {integrity: sha512-HpyHtiomh09wv6/83z+bhbkqVngIUdqNGEXRTIPg4sArVPMZ9UCXBrkQsHDRqdMUx0lBAcgB3IjlbdhkwHGaXA==}
dependencies: dependencies: