mirror of
https://github.com/fluencelabs/fluence-js.git
synced 2025-06-12 07:31:21 +00:00
fix(tests): Repair integration tests [fixes DXJ-506] (#364)
* Add test server * remove headless * Support for web-cra * Review fixes and bug fixes * Add error message
This commit is contained in:
@ -14,13 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ClientConfig,
|
||||
ConnectionState,
|
||||
IFluenceClient,
|
||||
RelayOptions,
|
||||
} from "@fluencelabs/interfaces";
|
||||
|
||||
import {
|
||||
RelayConnection,
|
||||
RelayConnectionConfig,
|
||||
@ -32,6 +25,13 @@ import { IMarineHost } from "../marine/interfaces.js";
|
||||
import { relayOptionToMultiaddr } from "../util/libp2pUtils.js";
|
||||
import { logger } from "../util/logger.js";
|
||||
|
||||
import {
|
||||
ClientConfig,
|
||||
IFluenceClient,
|
||||
ConnectionState,
|
||||
RelayOptions,
|
||||
} from "./types.js";
|
||||
|
||||
const log = logger("client");
|
||||
|
||||
const DEFAULT_TTL_MS = 7000;
|
||||
|
171
packages/core/js-client/src/clientPeer/types.ts
Normal file
171
packages/core/js-client/src/clientPeer/types.ts
Normal file
@ -0,0 +1,171 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Peer ID's id as a base58 string (multihash/CIDv0).
|
||||
*/
|
||||
export type PeerIdB58 = string;
|
||||
|
||||
/**
|
||||
* Node of the Fluence network specified as a pair of node's multiaddr and it's peer id
|
||||
*/
|
||||
export type Node = {
|
||||
peerId: PeerIdB58;
|
||||
multiaddr: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* A node in Fluence network a client can connect to.
|
||||
* Can be in the form of:
|
||||
* - string: multiaddr in string format
|
||||
* - Node: node structure, @see Node
|
||||
*/
|
||||
export type RelayOptions = string | Node;
|
||||
|
||||
/**
|
||||
* Fluence Peer's key pair types
|
||||
*/
|
||||
export type KeyTypes = "RSA" | "Ed25519" | "secp256k1";
|
||||
|
||||
/**
|
||||
* Options to specify key pair used in Fluence Peer
|
||||
*/
|
||||
export type KeyPairOptions = {
|
||||
type: "Ed25519";
|
||||
source: "random" | Uint8Array;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fluence JS Client connection states as string literals
|
||||
*/
|
||||
export const ConnectionStates = [
|
||||
"disconnected",
|
||||
"connecting",
|
||||
"connected",
|
||||
"disconnecting",
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Fluence JS Client connection states
|
||||
*/
|
||||
export type ConnectionState = (typeof ConnectionStates)[number];
|
||||
|
||||
export interface IFluenceInternalApi {
|
||||
/**
|
||||
* Internal API
|
||||
*/
|
||||
internals: unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public API of Fluence JS Client
|
||||
*/
|
||||
export interface IFluenceClient extends IFluenceInternalApi {
|
||||
/**
|
||||
* Connect to the Fluence network
|
||||
*/
|
||||
connect: () => Promise<void>;
|
||||
|
||||
/**
|
||||
* Disconnect from the Fluence network
|
||||
*/
|
||||
disconnect(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Handle connection state changes. Immediately returns current connection state
|
||||
*/
|
||||
onConnectionStateChange(
|
||||
handler: (state: ConnectionState) => void,
|
||||
): ConnectionState;
|
||||
|
||||
/**
|
||||
* Return peer's secret key as byte array.
|
||||
*/
|
||||
getPeerSecretKey(): Uint8Array;
|
||||
|
||||
/**
|
||||
* Return peer's public key as a base58 string (multihash/CIDv0).
|
||||
*/
|
||||
getPeerId(): string;
|
||||
|
||||
/**
|
||||
* Return relay's public key as a base58 string (multihash/CIDv0).
|
||||
*/
|
||||
getRelayPeerId(): string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration used when initiating Fluence Client
|
||||
*/
|
||||
export interface ClientConfig {
|
||||
/**
|
||||
* Specify the KeyPair to be used to identify the Fluence Peer.
|
||||
* Will be generated randomly if not specified
|
||||
*/
|
||||
keyPair?: KeyPairOptions;
|
||||
|
||||
/**
|
||||
* Options to configure the connection to the Fluence network
|
||||
*/
|
||||
connectionOptions?: {
|
||||
/**
|
||||
* When the peer established the connection to the network it sends a ping-like message to check if it works correctly.
|
||||
* The options allows to specify the timeout for that message in milliseconds.
|
||||
* If not specified the default timeout will be used
|
||||
*/
|
||||
skipCheckConnection?: boolean;
|
||||
|
||||
/**
|
||||
* The dialing timeout in milliseconds
|
||||
*/
|
||||
dialTimeoutMs?: number;
|
||||
|
||||
/**
|
||||
* The maximum number of inbound streams for the libp2p node.
|
||||
* Default: 1024
|
||||
*/
|
||||
maxInboundStreams?: number;
|
||||
|
||||
/**
|
||||
* The maximum number of outbound streams for the libp2p node.
|
||||
* Default: 1024
|
||||
*/
|
||||
maxOutboundStreams?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the default TTL for all particles originating from the peer with no TTL specified.
|
||||
* If the originating particle's TTL is defined then that value will be used
|
||||
* If the option is not set default TTL will be 7000
|
||||
*/
|
||||
defaultTtlMs?: number;
|
||||
|
||||
/**
|
||||
* Property for passing custom CDN Url to load dependencies from browser. https://unpkg.com used by default
|
||||
*/
|
||||
CDNUrl?: string;
|
||||
|
||||
/**
|
||||
* Enables\disabled various debugging features
|
||||
*/
|
||||
debug?: {
|
||||
/**
|
||||
* If set to true, newly initiated particle ids will be printed to console.
|
||||
* Useful to see what particle id is responsible for aqua function
|
||||
*/
|
||||
printParticleId?: boolean;
|
||||
};
|
||||
}
|
@ -23,9 +23,16 @@ interface PackageJsonContent {
|
||||
const packageJsonContentString = `__PACKAGE_JSON_CONTENT__`;
|
||||
let parsedPackageJsonContent: PackageJsonContent | undefined;
|
||||
|
||||
const PRIMARY_CDN = "https://unpkg.com/";
|
||||
|
||||
export async function fetchResource(pkg: string, assetPath: string) {
|
||||
/**
|
||||
* @param pkg name of package
|
||||
* @param assetPath path of required asset in given package
|
||||
* @param root CDN domain in browser or file system root in node
|
||||
*/
|
||||
export async function fetchResource(
|
||||
pkg: string,
|
||||
assetPath: string,
|
||||
root: string,
|
||||
) {
|
||||
const packageJsonContent =
|
||||
parsedPackageJsonContent ??
|
||||
// TODO: Should be validated
|
||||
@ -55,7 +62,8 @@ export async function fetchResource(pkg: string, assetPath: string) {
|
||||
? assetPath.slice(1)
|
||||
: assetPath;
|
||||
|
||||
return fetch(
|
||||
new globalThis.URL(`${pkg}@${version}/` + refinedAssetPath, PRIMARY_CDN),
|
||||
);
|
||||
const url = new globalThis.URL(`${pkg}@${version}/` + refinedAssetPath, root);
|
||||
return fetch(url).catch(() => {
|
||||
throw new Error(`Cannot fetch from ${url.toString()}`);
|
||||
});
|
||||
}
|
||||
|
@ -18,7 +18,18 @@ import fs from "fs";
|
||||
import module from "module";
|
||||
import path from "path";
|
||||
|
||||
export async function fetchResource(pkg: string, assetPath: string) {
|
||||
/**
|
||||
* @param pkg name of package
|
||||
* @param assetPath path of required asset in given package
|
||||
* @param root CDN domain in browser or file system root in node
|
||||
*/
|
||||
export async function fetchResource(
|
||||
pkg: string,
|
||||
assetPath: string,
|
||||
root: string,
|
||||
) {
|
||||
// TODO: `root` will be handled somehow in the future. For now, we use filesystem root where js-client is running;
|
||||
root = "/";
|
||||
const require = module.createRequire(import.meta.url);
|
||||
const packagePathIndex = require.resolve(pkg);
|
||||
|
||||
@ -33,7 +44,7 @@ export async function fetchResource(pkg: string, assetPath: string) {
|
||||
throw new Error(`Cannot find dependency ${pkg} in path ${posixPath}`);
|
||||
}
|
||||
|
||||
const pathToResource = path.join(packagePath, assetPath);
|
||||
const pathToResource = path.join(root, packagePath, assetPath);
|
||||
|
||||
const file = await new Promise<ArrayBuffer>((resolve, reject) => {
|
||||
// Cannot use 'fs/promises' with current vite config. This module is not polyfilled by default.
|
||||
|
@ -19,14 +19,14 @@ import path from "path";
|
||||
import process from "process";
|
||||
import url from "url";
|
||||
|
||||
import type {
|
||||
ClientConfig,
|
||||
ConnectionState,
|
||||
RelayOptions,
|
||||
} from "@fluencelabs/interfaces";
|
||||
import { BlobWorker, Worker } from "threads/master";
|
||||
|
||||
import { ClientPeer, makeClientPeerConfig } from "./clientPeer/ClientPeer.js";
|
||||
import {
|
||||
ClientConfig,
|
||||
ConnectionState,
|
||||
RelayOptions,
|
||||
} from "./clientPeer/types.js";
|
||||
import { callAquaFunction } from "./compilerSupport/callFunction.js";
|
||||
import { registerService } from "./compilerSupport/registerService.js";
|
||||
import { MarineBackgroundRunner } from "./marine/worker/index.js";
|
||||
@ -34,38 +34,49 @@ import { doRegisterNodeUtils } from "./services/NodeUtils.js";
|
||||
|
||||
import { fetchResource } from "#fetcher";
|
||||
|
||||
const DEFAULT_CDN_URL = "https://unpkg.com";
|
||||
|
||||
const isNode =
|
||||
// process.release is undefined in browser env
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
typeof process !== "undefined" && process.release?.name === "node";
|
||||
|
||||
const fetchWorkerCode = async () => {
|
||||
const resource = await fetchResource(
|
||||
"@fluencelabs/marine-worker",
|
||||
"/dist/browser/marine-worker.umd.cjs",
|
||||
);
|
||||
|
||||
return resource.text();
|
||||
};
|
||||
|
||||
const fetchMarineJsWasm = async () => {
|
||||
const resource = await fetchResource(
|
||||
"@fluencelabs/marine-js",
|
||||
"/dist/marine-js.wasm",
|
||||
);
|
||||
|
||||
return resource.arrayBuffer();
|
||||
};
|
||||
|
||||
const fetchAvmWasm = async () => {
|
||||
const resource = await fetchResource("@fluencelabs/avm", "/dist/avm.wasm");
|
||||
return resource.arrayBuffer();
|
||||
};
|
||||
|
||||
const createClient = async (
|
||||
relay: RelayOptions,
|
||||
config: ClientConfig,
|
||||
): Promise<ClientPeer> => {
|
||||
const CDNUrl = config.CDNUrl ?? DEFAULT_CDN_URL;
|
||||
|
||||
const fetchWorkerCode = async () => {
|
||||
const resource = await fetchResource(
|
||||
"@fluencelabs/marine-worker",
|
||||
"/dist/browser/marine-worker.umd.cjs",
|
||||
CDNUrl,
|
||||
);
|
||||
|
||||
return resource.text();
|
||||
};
|
||||
|
||||
const fetchMarineJsWasm = async () => {
|
||||
const resource = await fetchResource(
|
||||
"@fluencelabs/marine-js",
|
||||
"/dist/marine-js.wasm",
|
||||
CDNUrl,
|
||||
);
|
||||
|
||||
return resource.arrayBuffer();
|
||||
};
|
||||
|
||||
const fetchAvmWasm = async () => {
|
||||
const resource = await fetchResource(
|
||||
"@fluencelabs/avm",
|
||||
"/dist/avm.wasm",
|
||||
CDNUrl,
|
||||
);
|
||||
|
||||
return resource.arrayBuffer();
|
||||
};
|
||||
|
||||
const marineJsWasm = await fetchMarineJsWasm();
|
||||
const avmWasm = await fetchAvmWasm();
|
||||
|
||||
@ -194,11 +205,9 @@ export const Fluence: FluencePublicApi = {
|
||||
},
|
||||
};
|
||||
|
||||
export type {
|
||||
IFluenceClient,
|
||||
ClientConfig,
|
||||
CallParams,
|
||||
} from "@fluencelabs/interfaces";
|
||||
export type { CallParams } from "@fluencelabs/interfaces";
|
||||
|
||||
export type { ClientConfig, IFluenceClient } from "./clientPeer/types.js";
|
||||
|
||||
export type {
|
||||
ArrayType,
|
||||
|
@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { KeyPairOptions } from "@fluencelabs/interfaces";
|
||||
import {
|
||||
generateKeyPairFromSeed,
|
||||
generateKeyPair,
|
||||
@ -26,6 +25,8 @@ import { createFromPrivKey } from "@libp2p/peer-id-factory";
|
||||
import bs58 from "bs58";
|
||||
import { toUint8Array } from "js-base64";
|
||||
|
||||
import { KeyPairOptions } from "../clientPeer/types.js";
|
||||
|
||||
export class KeyPair {
|
||||
private publicKey: PublicKey;
|
||||
|
||||
|
@ -14,9 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { RelayOptions } from "@fluencelabs/interfaces";
|
||||
import { multiaddr, Multiaddr } from "@multiformats/multiaddr";
|
||||
|
||||
import { RelayOptions } from "../clientPeer/types.js";
|
||||
|
||||
import { isString } from "./utils.js";
|
||||
|
||||
export function relayOptionToMultiaddr(relay: RelayOptions): Multiaddr {
|
||||
|
@ -18,16 +18,15 @@ import { promises as fs } from "fs";
|
||||
|
||||
import * as api from "@fluencelabs/aqua-api/aqua-api.js";
|
||||
import {
|
||||
ClientConfig,
|
||||
FunctionCallDef,
|
||||
JSONArray,
|
||||
PassedArgs,
|
||||
RelayOptions,
|
||||
ServiceDef,
|
||||
} from "@fluencelabs/interfaces";
|
||||
import { Subject, Subscribable } from "rxjs";
|
||||
|
||||
import { ClientPeer, makeClientPeerConfig } from "../clientPeer/ClientPeer.js";
|
||||
import { ClientConfig, RelayOptions } from "../clientPeer/types.js";
|
||||
import { callAquaFunction } from "../compilerSupport/callFunction.js";
|
||||
import { IConnection } from "../connection/interfaces.js";
|
||||
import { DEFAULT_CONFIG, FluencePeer } from "../jsPeer/FluencePeer.js";
|
||||
|
Reference in New Issue
Block a user